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.
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:
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:
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:
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:
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:
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:
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:
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".
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
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.
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.
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
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
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.
- -- Jered