Linux file permissions are strange and wondrous things. Start down the path of understanding by looking at the core concepts behind them before moving on to practical applications.
In a multi-user environment like Linux it’s important to control which users can modify or delete various files on the system. This control isn’t just a necessary security precaution — it prevents catastrophic accidents. If a user can only affect a minimum number of files, there’s less chance that a mistyped command or a typo in a script will destroy an essential file or publish confidential information to a public web site.
To approach the problem of managing file access, we first need to understand the concepts of file ownership and file permissions. Once we’ve wrapped our brains around those basics we can move on to the matter of actually checking and changing file access details.
Note that this ownership and permission stuff also applies to directories, since they’re basically a special kind of file as far as the filesystem is concerned. The way permissions can be applied to directories is a little different from regular files, but the basic concepts are the same, so we’ll mostly just talk about “files” and keep in mind that it can mean “directories” too.
So we’ll start with one of our two basic concepts: File ownership.
The basics: Ownership
Every file and directory on a Linux file system has an owner. Just like ownership in “real life”, the owner of a file is the one who gets to assign permissions for the file. If user “mom” owns the file “lawndarts”, you’ll need mom’s permission to play with lawndarts. Maybe she’ll let you mess with lawndarts, or maybe she’ll deny you access to it altogether. Or she’ll just let you look at lawndarts without getting to play with it, not knowing how much it tortures you to see them sitting there on a high shelf, unreachable, just because she thinks you’ll put your eye out.
Sorry. Got a little sidetracked. Where was I?
Right, file ownership. The user who owns a file gets to change its permissions. Everything after that depends on the permissions that are set — whether someone (even the owner!) can read the file, or change it, or delete it. It’s a simple privilege, but far-reaching in its impact.
While every file has a user who owns it and can control its permissions, every file also belongs to a group. A “group”, for the purposes of Linux files, describes a set of users who have file permissions that may be different from the common user. A user can be in more than one group, but a file can only be in one group.
Group ownership is a handy way to let a file owner assign one set of permissions to a file for people he doesn’t know (“You can look, but can’t touch”), and another set of permissions for people he trusts with the file (“You can look andtouch. But no one else”).
A normal user can control a file’s permissions, but can’t actually give a file away. To do that, you need to use a third party to broker the deal – the superuser. The superuser is more commonly known as “root”. You may have run into him before.
If you aren’t logged in as root that usually means that you’ll need to use “sudo” to use root privileges to change a file’s owner.
The filesystem is more flexible about changing a file’s group. You can still use root to change the group, but the file’s owner can also switch a file to another group so long as the user belongs to the group in question.
The main command used to change a file’s owner or group is “chown”. The most common syntax used with chown is:
chown user:group file1 file2 file3
Breaking that down, the “user” in the example above is the user you want to own the file, and “group” is the group you want the file to belong to. A colon separates the two. After the user/group pair you list one or more files that will be affected by the change.
The user and the group are both optional with chown, though of course if you omit both you won’t actually change anything. If you want to just change the owner for a file, you can use:
chown user file1 file2 file3
If you want to use chown to just change the group, make sure to include the colon even though you won’t be specifying a user:
chown :group file1 file2 file3
It’s important to note that chown also accepts a period in place of the colon when separating the user and group names. This is outdated behavior, but you’ll sometimes see it in old scripts or documentation so chown still supports it. If you see a period in someone’s example you can use it with chown and it will work fine, but I’d still recommend using the colon instead.
The reason I recommend against the use of a period as the chown separator is that it’s possible (discouraged, and often made difficult, but still possible) to create a user that has a period in its name. You will probably never, ever run into this, but I like to be thorough.
Fortunately if you do encounter a username with a period in it and want to use chown with it, chown will handle the period gracefully if you include a colon between the user and group names. If you don’t want to change the group, you can just leave that part blank but still include the colon, as in:
chown john.smith: file1 file2 file3
If you don’t like that messy colon hanging around when you just want to change the group for a file, there’s an alternative command:
chgrp group file1 file2 file3
This works just like “chown :group”, but it’s easier to type and read.
There are times you’ll want to change the owner of not just a particular directory, but everything inside the directory and its subdirectories. When that comes up, just use the “-R” flag to make a “recursive” change:
chown -R user:group directoryname
The “-R” flag works with chgrp as well. With both commands the change will first be applied to the parent directory, then the command will iterate through everything inside the directory (including subdirectories) and apply the change to each of them as well.
You run into a special circumstance when you try to use chown or chgrp with a symlink. A symlink is kind of like an alias for another file, similar to a shortcut in Windows. Rather than apply the change to the symlink itself, by default the filesystem will apply the change to the target of the symlink. So if the symlink “link” points to the file “thefile”, consider this command:
chown user:group link
When that command executes, the system will actually change the owner and group for the target file “thefile”. The ownership of the symlink “link” will remain the same.
If you want to change the owner and/or group of a symlink, use the “-h” flag for chown and chgrp, as in:
chown -h user:group link
The other basics: Permissions
Now that we hopefully understand ownership — namely, that it allows the control of permissions — let’s talk about permissions themselves.
There are two parts to permissions. The first involves what someone is allowed to do with a file, and the second involves who that “someone” can be. Let’s look at the possibilities for “what” before we go into the “who”.
What can be done
When controlling what can be done to a file or directory, there are three categories of actions: read, write, and execute.
What is specifically allowed or disallowed can be different for files and directories, so we’ll talk about both for each category.
The “read” permission controls, well, who can read a file. If you don’t have read permissions for a file you can’t look inside and see its contents.
The “read” permission for a directory controls whether or not you can see a list of the files in the directory. Note, however, that to do so you will also need “execute” permission for the directory.
The “write” permission on a file controls whether or not you can change the file’s contents. If you want to edit the text in an html file, for example, you need write permission before you can do so.
The “write” permission on a directory controls whether or not you can add, delete, or rename files in that directory.
Note that the way write permissions work, only the write permission on the enclosing directory will affect whether or not you can rename or delete a file. Well, at the operating system level, anyway — some programs, like “rm”, will do a check and prevent you from deleting a file you don’t own. There’s nothing stopping another program that doesn’t have a similar check built into it from deleting a file you can’t write to and don’t own.
The rename and delete permissions might seem a little weird until you consider what we mentioned earlier: The filesystem considers a directory to be a special kind of file. If you think of a directory as a special file that lists the files it contains and how to find them on the disk, it might make a bit more sense that write permission for the directory would let you delete or change that list.
Note that, just like read, to exercise your write permissions in a directory you will also need “execute” permission for said directory.
The “execute” permission for a file allows you to run that file from the command line. In order to run any command (“chown”, “ls”, “rm”, etc.), you have to have execute permission for the file representing that command. If you try to run a command and get a “permission denied” error, it’s because you don’t have execute permission.
The “execute” permission for a directory lets you perform an operation in that directory, or to change your working directory (“cd”) to that directory.
Remember those two “Note that…” lines in the sections on read and write, about needing execute permission for a directory too? This is why. Even if you have read permission for a directory you can’t actually run the “ls” command inthat directory to see the list of files unless you have execute permission. Otherwise you try to run “ls” and get blocked before the system can even check for read permission.
Basically, to affect anything inside a directory, you need to be able to “execute” the directory first.
Who can do what
Now that we have an idea of what permissions are available, let’s look at what categories we can use to control who actually gets affected by those permissions. The categories are: user, group, and other.
The “user” permission category refers to permissions that apply to the owner of the file. It’s the only category that specifically targets only one user, because only one user can own the file.
It’s tempting to think of this category as “owner”, but I recommend against it. You’ll see why in successive articles, but the main reason is that there’s already another category that starts with an “o” (that being “other”), and that can get confusing. Stick to “user”, as in “the user who owns the file”, since that can be abbreviated to “u”. Trust me for now.
The “group” category refers to users that are in the same group as the file. If the file is in the group “devs”, and the file has write permission for its group, that would mean that users in the “devs” group will have write access to the file.
The “other” category is a catch-all for everyone who doesn’t fall under “user” or “group”. You use this category to determine whether that faceless mass of anonymous users will be able to read the file, or edit it, or run it as a command.
It’s important to note that permission categories are applied in the above order, and the first permission category the system finds for a user is the only one it will apply. If you’re the owner of the file, your permissions are whatever are set for “user”, so the system won’t bother checking the group permissions for the file — it’s already found what it’s going to use.
The reason this is important is that if you set a permission on “other”, that permission will not be applied to the file’s owner or to anyone in that file’s group. Those users will get the permission set in “user” or “group”, respectively.
If you don’t set “read” permission on a file for the “group” category but do set it for the “user” and “other” categories, that will mean that users in the file’s group will not have read access but everyone else will. Look at it as an easy way to prevent access for a small group of users without needing to add everyone else to a more privileged group. Just put the offending users and the file in the “outcasts” group and remove group read access for for the file in question, and you’re set.
Permissions plus users
Combining ownership, user categories and permissions gives you a lot of options for controlling access to files and directories. A few common examples:
If you make a file read-only for “other” but let “user” and “group” write to it, then you can establish a group of editors for a file while still allowing other users (like the one running the web server, for example) to read it. Just add the privileged users to the same group as the file.
Setting “read” permission for “user” but removing it from “group” and “other” will ensure that only the owner of the file can view its contents. This is handy when you’re just using a file for your own testing purposes, or don’t want someone else coming along and criticizing a document until you’re done writing it.
Setting “execute” permission for a file allows it to be run as a command, so if you have a command you only want specific users to be able to run, remove “execute” permission on the file for the “other” category.
Directories get the same treatment. Many system log directories are set to “read” and “execute” by just “user” (usually root) and exclude those permissions from other categories to ensure that only someone with superuser access will be able to view the logs, no matter what permissions are set on the files themselves.
Why root exists
All of this leads up to the root user’s reason for being: access and control. The root user can change the ownership and permissions of any file or directory on the system. That user can also interact with files and directories as if it has the most permissive permissions available for the file in question.
If “user” can’t read a file but “other” can, root can read it. Similarly, if “user” can read the file but “other” can’t, then root can still read the file. But if no category has “read” permission (not user, not group, and not other), then root can’t read the file either.
This behavior is most useful for files you really don’t want to accidentally change. If write permissions are removed from all categories for a file, then not even root can change the file’s contents without changing those permissions. Though it’s useful to note that, going back to what we discussed about the way permissions work with directories, if you want to prevent a file from being deleted by root you’ll have to completely remove the “write” permission from the enclosing directory as well.
We actually won’t go into that in this article, but we will in the next article. The command is “chmod”, and it’s complicated, and this article is running long already.
With a basic understanding of how file permissions work in Linux, you should be better prepared to secure files from accidental or malicious harm. You should also be able to keep an eye out for errors that can be caused by restrictive file permissions, like an application being unable to write to its log (no write permission for the user that owns the process), or a web server being unable to serve an html file (no read permission, or the directory doesn’t have execute permission).