User Tools

Site Tools


linux_file_permissions

This is an archive of the Slicehost article located at http://articles.slicehost.com/2010/7/17/linux-file-permission-concepts

This article is NOT licensed under CC Attribution-Share Alike 3.0 Unported.

Linux file permission concepts

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.

File access

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.

File group

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 and touch. But no one else”).

Changing ownership

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.

chown

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

chgrp

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.

Using -R

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.

Read

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.

Write

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.

Execute

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 in that 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.

User

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.

Group

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.

Other

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.

Category priority

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.

Changing permissions

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.

Summary

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).

A bit confusing? Definitely. Useful? That too. All this stuff about file ownership and permissions makes more sense once you learn how to view the permissions, which will be the topic of the next article in this series.


Using chmod, part 1 - symbolic mode

We've done the thinking and the seeing, now to start the doing. Continuing our series on file permissions, we look at using the chmod command.

Changing permissions

In the previous article in this series we learned how to use the “ls” command to check the permissions and ownership of files and directories. Now we can look at the command we use to change those permissions. That command is “chmod”.

chmod

The basic format for chmod looks something like:

chmod [permissions] [file1 file2 file3...]

The chmod command looks a lot like chown — the part you're changing comes first (for chmod, the permissions), then you list one or more file targets for the command.

Like the chown command, you can use “-R” to tell chmod to apply permissions to everything in a directory:

chmod -R [permissions] [directory]

With the format of the command in mind, let's look at the first of two ways permissions can be assigned: symbolically.

Symbolic permissions

The symbolic approach to chmod and permissions is a bit easier to understand, so we'll start there. The general format is to specify an “accessor”, which designates the permissions category being modified, then an operator like “=” or “+” or “-”, then the permissions themselves.

That's right, what I just described is the easy way. Don't focus on that too much, focus on how brilliant you will be when, at the end of this, you are a file permissions expert.

Accessors - ugo and a

The first part of setting permissions is the “accessor”, which describes the category the permissions will be applied to. Each category name has a one-letter abbreviation:

u refers to the user category, the one that applies to the file owner

g refers to the group category, that applies to users that share a group with the file

o refers to the other category, the category that applies to everyone else

There's one more accessor of note:

a refers to all categories at once

Permissions - rwx

The permissions are represented by the same letters as they are in a directory listing — read, write, and execute are r, w, and x, respectively.

Combining the letters

To connect the accessors to the permissions you'll use an operator. The first operator we'll look at is a straightforward assignment:

= assigns the listed permissions to the listed categories.

You can list more than one category or permission on each side of the operator. For example, to give everyone every permission for a file, you could run:

chmod ugo=rwx file1

Though granted, there's an “a” operator you could use, so that would probably look cleaner as:

chmod a=rwx file1

You usually don't want to use the same permissions for every user unless you're making a file read-only (there are often better ways to solve a problem than giving everyone write access). You can send multiple operations to chmod by separating them with commas (no spaces):

chmod u=rwx,g=rx,o=rx file1 file2

And again, just to be clear, you can combine accessors to achieve the same result:

chmod u=rwx,go=rx file1 file2

Both of the above give the owner full access and everyone else read and execute permissions.

Adding and subtracting bits

Aside from the “=” operator, you can also add or subtract permissions:

+ adds the listed permissions to what is already there for the listed categories. If the requested permissions are already in place, nothing is changed.

- removes the listed permissions from what is already there for the listed categories. If the requested permissions aren't there to begin with, nothing is changed.

To just add group write permissions to some files without changing any other permissions, you can run:

chmod g+w file1 file2 file3

If you want to remove read and execute access from everyone but the file owner, you can run:

chmod go-rx file1 file2 file3

If you omit the accessor, the change will be applied to all categories (as if you'd used the “a” accessor). So to remove all execute access to a file, you can just type:

chmod -x file1 file2

It's generally safer to keep in the habit of specifying the category, or using “a” if you want to change permissions for everyone at once.

Neat trick permission - X

There's a special permission option you can send to chmod: a capital X.

X refers to execute permission just for directories and for files that already have execute permission for one or more categories.

Using “X” for a permission is kind of like telling chmod to intelligently change execute permissions. With X, you won't add execute permissions to files you haven't already made executable. It's much safer and cleaner than applying executable permissions to files you don't actually want to execute as commands.

The X permission is usually used when you're making changes to everything in a directory and its subdirectory using the “-R” flag. For example:

chmod -R a+X directory

The above command would grant everyone execute permission for the directory in question, all subdirectories, and any files for which someone already has execute permissions.

Or, to illustrate the effect through a directory listing, if you start with these files and directories:

-rwxr-x--- 1 demo demo      0 2010-07-15 01:40 foo
-rw-r----- 1 demo www-data    0 2010-01-21 15:55 gee.txt
drwxrwx--- 2 demo demo   4096 2010-07-16 18:18 testsub

And then run:

chmod o+rX *

Then you will apply read permissions and execute permissions to the “other” category as appropriate for all files and directories (the “*” in the command is a shortcut for all files):

-rwxr-xr-x 1 demo demo      0 2010-07-15 01:40 foo
-rw-r--r-- 1 demo www-data    0 2010-01-21 15:55 gee.txt
drwxrwxr-x 2 demo demo   4096 2010-07-16 18:18 testsub

Note that “gee.txt” did not get get the execute permission set, but everything else did. Everything else was either a directory or could already be executed by user or group.

You can use the X permission when assigning permissions directly:

chmod -R u=rwX,go=rX directory

That command would set read and write permissions for the user and read permissions for everyone else on all files in the directory, then add execute permission to the directory, all subdirectories, and any files that were already executable.

It's possible to use X with the “-” (remove) operator, but since it behaves the same as “x” (since it just removes the execute bit) there isn't much point to using X that way.

Still, the main point, and the reason I explained this one at such length: When changing permissions on a directory and all its contents you're much better off using “X” than “x”. Adding the execute bit to files that don't need it can be a potential security headache, and it can make it harder to remember which files you actually want to be executable when everything's already executable.

Summary

Now we're getting somewhere! Now that you can both check and change permissions, you can both hunt down problems and fix them. You also know enough to be able to set up some fancy permission combinations using users and groups. If some instructions tell you to make a file or directory writeable by everyone, you'll find it much more secure to use group permissions to add that access to just the users and processes that actually need it.

Don't stop now, though. The next article describes another way to use chmod. It's not a very intuitive way to set permissions, but it's useful, and more importantly, it's widely used. Someday you'll need to understand what it means when someone says to set a directory to “777” (and why to say no). Learning about using chmod with octal mode will help you with that.


Using chmod, part 2 - octal mode

Now we look at the other way chmod can be used - with numbers. This is the more commonly-used format, but also the least user-friendly.

The other chmod: with math

You've learned how to use chmod with symbolic values, but there's one more approach to chmod you should learn.

You will probably hate me for this, but I'm going to tell you about the binary number system now, and a little bit about the octal number system. There's a good reason though: The other way to assign permissions with chmod uses octal numbers, and it's the approach you'll come across most frequently in documentation.

Symbolic permission assignment is a newcomer on the scene, while using octal numbers has always worked with chmod. It's also a pretty readable system once you get used to it. It's painful to learn, but it's worth understanding how it works. So brace yourself, and read on.

Number systems

You might remember the binary system from math. They might also have called it “base 2”. If you have not learned about it before, however, let's start by looking closely at the numbers you're used to working with.

Our “normal” number system is what's known as “base 10”. Each digit of a number ranges from 0 to 9 — ten numbers in all. If a digit would be added to in a way that would make it be 10 or more, the extra numbers are added to the next higher digit in the numeral. That way the digits will always be less than 10 - the “base” value.

This also means that each digit in a number can be expressed in terms of powers of 10. And by “powers” I mean the successive results of multiplying by 10, except the first digit, which is the result of multiplying by 1.

The number “345”, for example, breaks down like this:

3 x 10 x 10 = 300
4 x 10 = 40
5 x 1 = 5

300 + 40 + 5 = 345

Note that when you get down to the adding part, you're adding a three-digit number to a two-digit number to a one-digit number. When they're combined into one three-digit number you can see where each digit came from.

Now, when you move to a different “base”, what you're basically changing is what number you multiply by to get the value of each digit in the number. So if you go from “base 10” to “base 8”, the value of each digit in the number “345” changes. If you want to see what 345 in “base 8” looks like in our usual “base 10” system, you do some math that looks like this:

3 x 8 x 8 = 192
4 x 8 = 32
5 x 1 = 5

192 + 32 + 5 = 229

Weird, huh? What we see from that math is that “345 base 8” is equal to “229 base 10”. That also means that “10” means something different in each number system. In base 10:

1 x 10 = 10
0 x 1 = 0

10 + 0 = 10

But in base 8:

1 x 8 = 8
0 x 1 = 0

8 + 0 = 8

And before you get too puzzled about “10=8”, remember that we're using different “base” systems there. If we go back to the start of this discussion, we noted that in “base 10” no digit is higher than 9 - one less than 10. It's the same way in “base 8” - no digit goes up to 8, only to 7. If you get to 8, you insert a new digit in front of the number to represent the 8. Thus, “10 base 8” equals “8 base 10”.

The binary number system

This leads us to the binary system, which is “base 2”. No digit will be higher than 1 when we're working with binary (each digit can only be 0 or 1). That means “10 base 2” is, in base 10:

1 x 2 = 2
0 x 1 = 0

2 + 0 = 2

And “100 base 2” in base 10 is:

1 x 2 x 2 = 4
0 x 2 = 0
0 x 1 = 0

4 + 0 + 0 = 4

The digits proceed from there the same way - multiplying by 2 each time. So a list of the values of the digits in a base 2 number progress like:

1
2
4
8
16
32
...

Each value is a double of what came before.

Permissions as binary numbers

Now that you've got that jumble of information bouncing around in your head, let's look at the numerical equivalents of permissions, as far as chmod is concerned. In base 10, our usual number system, the values are:

r = 4
w = 2
x = 1

The reason those are the values assigned to each permission is because those numbers correspond to digits in the binary number system we were just discussing. In binary terms, then…

r = 4 base 10 = 100 base 2
w = 2 base 10 = 10 base 2
x = 1 base 10 = 1 base 2

100 + 10 + 1 = 111 (in any number system)

And now we reach the point where I explain why you really care about what a binary number is. Because if you look at the permissions on a file, you'll recall that they're expressed, in order, as “rwx”. Or, if a permission is absent, a dash takes its place — like “r-x” if there's no write permission for that category.

If you think of each of those permissions as a binary digit, where “-” is 0 and anything else is 1, they could be written like this:

rwx = 111
rw- = 110
r-x = 101
r-- = 100

And if you turn those into base 10 numbers, it would look like:

rwx = 111 base 2 = 4 + 2 + 1 = 7
rw- = 110 base 2 = 4 + 2 + 0 = 6
r-x = 101 base 2 = 4 + 0 + 1 = 5
r-- = 100 base 2 = 4 + 0 + 0 = 4

And in that way, with some funky math, we turn each of those permission trios into a single number! And now we can see why I used “base 8” as an example above: None of those numbers are above 7, so they could be expressed as single digits in base 8. Which leads us to…

Combined, and in octal

Another word for “base 8” is “octal”, the same way another word for “base 2” is “binary” (and another word for “base 10” is “decimal”). The word “octal” shares the same root as “octopus”, a creature named for its 8 legs, if you want an easier way to remember that. And you'll want to remember that, because I'll be talking about octal numbers now instead of the more awkward “base 8”.

As you saw, a trio of permissions can be expressed as binary digits, and those digits represent a number that can be turned into a single octal digit. If that sentence made no sense, go back and try reading the previous sections again. Now that you've at least skimmed all that stuff about number systems, the earlier sections will hopefully be more comprehensible.

If it still doesn't make sense, post in the comments. You can help me figure out how to make it make sense.

Now, you may also recall that when we talk about a file's permissions, there are three categories: user, group, and other. And those categories are listed in order in a directory listing, just like each permission is listed in the same order each time.

So if you take the octal digit that expresses the permissions in each category, and you line them up in order, you get a three-digit octal number. And there you have it: How to set permissions with chmod in octal mode. Instead of “u=rwx,go=rx”, you would have “755”.

There are no relative assignments of permissions using octal. You either use a full three-digit octal number, or you don't use octal with chmod at all. That makes octal mode powerful (since you're assigning a lot of permissions with just three keystrokes), but also potentially lazy (since “755” sets everything to that permission, and doesn't distinguish between files and directories).

Octal examples

So now let's bring it all together to make that octal thing a little clearer. We'll look at some examples. First, a quick cheat sheet of commonly-used octal digits:

rwx = 7
rw- = 6
r-x = 5
r-- = 4

If you're not sure where those numbers came from, go back up and read the stuff about binary and octal again. Seriously, it's all worth it in the long run. I promise.

So. A common permission set for a directory is all access for the owner, and read and execute permissions for everyone else. In a long directory listing, a directory with those permissions might look like:

drwxr-xr-x 1 root root    622 Jan 11  2010 directory

In symbolic form, assigning these permissions would look like:

chmod u=rwx,go=rx directory

And in octal form, these permissions look like:

chmod 755 directory

If you're creating a file, you usually won't want to make it executable, so the default permissions for a regular file are usually read and write permissions for the owner, and just read permission for everyone else. In a directory listing that could look like:

-rw-r--r-- 1 root root    622 Jan 11  2010 file1

In symbolic form, assigning those permissions looks like:

chmod u=rw,go=r file1

And in octal form, it looks like:

chmod 644 file1

You can see why octal mode has stuck around as long as it has. Once you're used to it, it's easier to read a three-digit number than a bunch of letters and operators. It's just harder to understand the octal representation if you don't know what's going on behind the scenes.

Of course, if we want to combine the above permissions in a single statement (creating directories with executable permissions and files without), you can't do it with octal format. But you can with symbolic format thanks to that “X” permission we discussed earlier:

chmod u=rwX,go=rX directory file1

That's why I'd usually recommend using symbolic values with chmod if you're trying to change permissions for a bunch of files and directories all at once. Assigning “755” to everything in a directory could make a bunch of text files executable, which is messy and wrong (but easy). Assigning “u=rwX,go=rX” takes a little more thought to type, but applies the permissions more intelligently.

One more example before we leave this section: Assigning no permissions to a category. Let's say we want to set the permissions on a file so that it can be read and written to by its owner, and read by its group, but can't be accessed at all by everyone else. In a directory listing that might look like:

-rw-r----- 1 root root    622 Jan 11  2010 file1

In symbolic mode, assigning those permissions looks like:

chmod u=rw,g=r,o= file1

Notice how we didn't put anything after the last “=”. That works. It just means that category gets nothing.

In octal mode, the chmod command would look like:

chmod 640 file1

Note the “0”. The zero serves the same purpose as putting nothing after the equals sign in symbolic mode - that category gets no permissions.

A brief and final note before you are declared fit to truly play with permissions: Symlinks act differently with chmod.

Remember, a symlink is a pointer to another file or directory. As a result, a symlink can have an owner, but it doesn't have any permissions of its own - all the permissions are set on the target file. So if you have “symlink1” pointing to “file1”, then the command:

chmod 700 symlink1

would behave the same way as typing:

chmod 700 file1

This is logical, but it can also be dangerous when you have a bunch of symlinks in a directory and you recursively (with “-R”) change the permissions of everything within. To be on the safe side, chmod ignores symlinks when changing permissions recursively. So if you run:

chmod -R 700 directory

Then you'll set the 700 permissions (all for user, none for group or other) on the directory plus all the regular files and directories inside “directory”, but the permissions on the targets of all the symlinks inside “directory” will be left unchanged.

Summary

Wow, you actually made it through that? I'm impressed. I'm even more impressed if you understood even half of the stuff about chmod in one go — permissions are a pretty esoteric concept, considering how integral they are to working with Linux in general. So if you still feel a bit lost, that's actually pretty normal.

What I recommend now is to take the stuff we talked about so far and play with it. Get on a Linux system, make a new directory, cd into it, and then start making some more directories and files (you can use the “touch” command to create an empty file). Then go crazy with chmod. Add permissions, remove them, set them, and do an “ls -l” each time so you can see what happened. Practical experiments with chmod help a lot when trying to understand permissions.

Remember that you can test those permissions too. After you change permissions, see whether you can still create or delete files in a directory, or make changes to a file. You might also use “sudo” to run chown and chgrp to give files new owners and groups, then see what happens to your regular user's access to those files.

Once you understand permissions you'll be much better-equipped to both secure your system and to troubleshoot problems. A lot of errors can ultimately be traced back to permissions issues. A “403” error from a web site, for example, means “permission denied” - now that you understand permissions, you'll be able to hunt down the cause of that problem. Neat!

If you want to learn just about everything else about permissions and how they work in the file system, as well as some of the other file types you might see crop up in “ls -l” listings, continue to the next article. It talks about umasks and named pipes and stuff. They're the sorts of things it's good to know are there, even if you're not sure you'll ever actually use them.


Umask and unusual file permissions and types

In this last entry in our series on Linux file permissions we look at the umask and some more advanced file permissions. We also throw in some discussion of other file types you may see in a directory listing.

Odds and ends

We've covered the basics of file permissions in Linux, as well as how to view and change them. Now, in this final article of the series, we'll look at the rest of it. Bits and pieces that might be useful, or might just satisfy curiosity, or can help you avoid trouble down the line.

The umask

We'll start with the subject of “umask”, a means of controlling the permissions on files and directories when they're first created.

The umask is set when you log in, and is usually set in one of the default shell config files (like /etc/profile). You can override the umask for a particular user by setting their umask in the user's shell profile, usually in “~/.bashrc”. The setting looks something like:

umask 022

The umask octal value is kind of the reverse of chmod permissions — you set it with an octal value, but instead of specifying the permissions you want the created file to have, you specify what you don't want it to have. For comic book fans, think of it as Bizarro Permission.

In the example above, the “2” set for “group” and “other” means, instead of adding write permission to the created file, everything except write permission is added for those two categories. The “0” means all permissions are set for the file owner.

You will sometimes see the umask expressed as four digits, like “0022”. Both styles work. That first digit is for setting some special permissions, which we will describe shortly. But the quick version: You usually won't want to set those with umask, so if you send umask four digits just use a zero as the first digit.

Note that the default behavior for files is to omit the executable permission for all categories. So while the above example only omits the “write” permission, a file created with that umask would have the octal permissions “644”, while a directory would include the executable permissions, and thus be “755”.

If you prefer a mathematical way to look at it, take the maximum default permissions (777 for a directory, 666 for a file), then subtract the umask value to get the initial permissions.

Another example to illustrate the point:

umask 027

This one removes write from “group” and everything from “other”, making a file that can be read and written to by its owner, read by its group, and denies all access to everyone else. A created directory would be the same, but would also include “execute” for owner and group.

You can view the current umask setting for your shell session by typing simply:

umask

Symbolic values and umask

You will almost always see the umask set with the octal value assignment. This is mostly because of history and backward compatibility — older shells only support octal values for umask. But current Linux distributions ship with default user shells that support symbolic values for umask (like bash), so if you prefer to go symbolic, you should be fine.

One significant point of note about using symbolic values with umask is that you don't do the “use the reverse of what you want” thing like you do with octal umask. If you do an assignment of symbolic permissions with umask, it works a lot like it would if you used chmod. The one difference would be that the behavior of not assigning execute permission to regular files when they're created still applies.

To express the equivalent of “umask 022” with symbols, you can directly assign the permissions:

umask u=rwx,g=rx,o=rx

Again, noting that the “x” permission will only be applied to directories, not regular files. You can also use relative symbols with umask, but that can get a little tricky. If you use relative symbols with umask, like:

umask g+w

Then the adjustment is applied to whatever the current umask is set to. That can be confusing if the default umask gets changed later, though - imagine the above example if someone comes along later and takes group read and execute permission out of the default umask. You'll end up with files and directories that your group can write to but can't read or cd into.

So if you know you just want to change the umask for a particular category, it's best to just use something like:

umask g=rwx

That way you'll still be using the default for the “other” category, but you can be sure group will always have the permissions you need set.

It's handy to know that you can get the symbolic representation of the current umask by passing umask the “-S” option:

umask -S

For a umask that would create files with the default octal permission “644” and directories with “755”, the results of umask checks would look like:

$ umask
0022
$ umask -S
u=rwx,g=rx,o=rx

The high-order bits

There are some other types of permissions you can set that we haven't really talked about yet. They are the “high order” permissions. To set them with octal you need to use a four-digit octal number, and the first digit will represent the high-order permissions. The high-order permissions are setuid, setgid, and text (the “sticky bit”).

Since you may notice them lying around your file system and wonder about them, let's briefly cover what each is for, and how they look in an “ls -l”.

Setuid

If the setuid bit is set on a file, when you execute the file the process will run as if it were launched by the file's owner. If you're running as user “demo” and run a file owned by root that has “setuid” on it, then when the program runs it will run as if root launched it.

As you might imagine, you want to be careful with this one. The smallest of security holes in a program running as root can lead to pretty big exploits. For this reason most scripts won't even launch if “setuid” is set on them.

Setuid is represented by an “s” in the “user” category when viewed in ls. A file with setuid looks like:

-rwsr-xr-x 2 root root     122880 2010-04-14 20:12 sudo

When setuid is set on a directory, the system ignores it.

In octal representation, the setuid bit is “4”. So setting the permissions in octal for the sudo program above would look like:

chmod 4755 sudo

Symbolically, setuid is “s” added to the user category only. So adding setuid to sudo could look like:

chmod u+s sudo

Setgid

The setgid permission works like setuid, except it causes a file to run as the file's group instead of the group of the user that launched it. So a program with the setgid bit on it that's in the group “www-data” will always run as if it were launched by a user with the primary group “www-data”, whether the user that actually launched it is in “www-data” or not.

A file can have both setuid and setgid active at the same time.

Setgid looks the same as setuid in ls, it just appears in the group category instead of the user category:

-rwxr-sr-x 1 root crontab   31656 2009-05-12 21:58 crontab

In octal representation the setgid bit is “2”. So setting the permissions for crontab above would look like:

chmod 2755 crontab

Symbolically, setgid is “s” added to the group category only. So adding setgid to crontab could look like:

chmod g+s chmod

It's possible for a file to have setgid set, but not be executable by its group (it's also possible for this to happen with setuid, but is much less likely). When that happens, setgid is displayed as a capital “S” instead of the usual lowercase “s”. If you changed the permissions for crontab in the above example so that only root could run it, but kept setgid active, the end result would look like:

-rwxr-Sr-- 1 root crontab   31656 2009-05-12 21:58 crontab

Directories handle setgid differently. If setgid is set on a directory, every file created in that directory will be created with the directory's group instead of the creating user's group. Furthermore, new subdirectories will inherit the setgid bit from the parent directory.

The inheritance behavior of setgid on a directory can be useful if you want a particular directory and all its contents to always be accessible to users in a particular group. You can just put the setgid permission on the parent directory (and any existing subdirectories), then change the default umask so files and directories will be created with group write permissions.

Note that you can't use setuid or setgid with the “-R” flag for chmod (for recursive permission changes) — you have to set that permission on each file or directory individually.

The sticky bit

The “sticky bit” confuses a lot of people. There's a good reason for this: The sticky bit means different things to different versions of Unix. Fortunately we only need to worry about Linux, so we only have to talk about one implementation of the sticky bit.

The sticky bit is ignored when set on files.

When set on a directory, the sticky bit tells the system that files in that directory can only be renamed or deleted by the user that owns them (and root). The most common use for the sticky bit, and really the only one you're ever likely to need, is on /tmp:

drwxrwxrwt   5 root root  4096 2010-07-16 02:47 tmp

The “t” at the end of the permissions is the sticky bit. The letter hearkens back to the sticky bit's original meaning, which involved caching text in memory. A handy mnemonic might be to think of the sticky bit as the “tmp bit” or “text bit”, depending on which association might work best for you.

That's the trouble with using letters to abbreviate this stuff. Because “sticky bit” is a memorable name you'll run into a lot of instances of people mistakenly reading an “s” in a permissions list as the sticky bit, when “s” is actually setuid and setgid. You will now know better. Feel free to correct people when they say “sticky bit” when they mean “setuid” or “setgid”. Unless they are particularly large and ill-tempered, in which case it may be best to just let it slide.

Anyway, you probably won't want to set the sticky bit anywhere else. It's useful in /tmp because it makes the permissions there a little more restrictive than a directory usually would be with 777 permissions.

In octal representation, the sticky bit is “1”. So if you accidentally deleted /tmp (trust me, it can happen) and wanted to recreate it, you could set the octal permissions of your new /tmp with:

chmod 1777 /tmp

A high-order cheat sheet

To summarize the octal values of those high-order permissions:

setuid = 4
setgid = 2
sticky = 1

Other file types

There are file types other than regular files, directories and symlinks that you might see in directory listings, particularly in /dev. These special file types represent ways for programs to talk with other programs or with hardware.

They illustrate part of what made Unix so weird and special at its creation: Treating most interactions similarly to file interactions. It's not a perfect setup, but the biggest benefit is providing a simple and fairly standard way for programs to talk to other parts of the system.

You might not need to use any of these file types yourself but an overview can be helpful, if only to know something about what the system is doing behind the scenes. Mostly I cover them here because you might see them in a directory listing and want some idea of what the heck they are.

These file types can be recognized by the first letter in an “ls -l” result, where you'd usually see a “-” for a regular file, “d” for a directory, or “l” for a symlink.

Socket

A socket file is a special type of file that lets a program write to a network interface using the normal file system interface. Instead of doing a “write” and having the text wind up in a text file, the text gets sent to the network interface.

A socket file is labeled with an “s” in the first slot, as in:

srw-rw-rw- 1 root   root           0 2010-02-26 22:46 log

That particular example is a socket located at /dev/log. That socket can be used by programs (like “logger”) to send log entries to a syslog daemon without needing to connect to the daemon directly.

Named pipe

A named pipe basically lets one program put data into the pipe and have another program read it. It's usually created with the “mkfifo” command.

You might have been told at some point to “pipe” data from one program to another with the “|” separator. If so, then you've used an “unnamed pipe” before. A named pipe is like that, except it lives in the filesystem and can be reused.

A named pipe is labeled with “p” in the file type slot of a directory listing.

For example, a named pipe at /dev/xconsole might be used by syslog to send logging data to xconsole, which in turn would be displayed to a user running x-windows. In a directory listing it would look like:

prw-r----- 1 syslog adm            0 2010-07-15 17:09 xconsole

Block special file

A block special file is a representation of a block device in the file system. A block device is a piece of hardware that the system would read from or write to in “blocks” of data, like a hard drive.

A block special file is represented by a “b” in the directory listing. The hard drive at /dev/sda1 would look like:

brw-rw---- 1 root   disk      8,   1 2010-02-26 22:45 sda1

Character device

A character special file is an interface to a character device. A character device is similar to a block device, but instead of reading from or writing to the interface in blocks, the system talks to the device one character at a time.

Where a block device tends to be something that stores data for later retrieval (like a disk), a character device is usually one where the system only needs to send or receive data of a more immediate nature - like sending a file to a printer, or receiving keystrokes from a keyboard.

A character special file is labeled with a “c” in a directory listing.

For example, a terminal session is a character device, usually named something like /dev/tty1:

crw------- 1 root root 4, 0 Jun 30 03:29 /dev/tty1

Summary

You probably now know more than you ever wanted to about Linux file permissions and file types. What can I say? I like to be thorough. Most of it is the sort of information you may never need, but when you do (like when you need to change default file permissions, or want to send data easily between programs), it can save you some research time if you know something of what's possible beforehand.

linux_file_permissions.txt · Last modified: by zertrin