![]() |
|
|
|||||||
| Home | Forums | Register | Rules & FAQ | Members List | Arcade | Search | Today's Posts | Mark Forums Read |
| Tips and Tutorials Helpful articles from our Users. |
Other UNIX.COM Threads You Might Find Helpful
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| To give the "unzip" permissions & "create" file permissions | Mike1234 | HP-UX | 3 | 03-02-2008 01:34 PM |
| Unix permissions | mobershaw | SUN Solaris | 0 | 01-24-2006 02:06 PM |
| UNIX File Permissions | jerardfjay | UNIX for Advanced & Expert Users | 3 | 03-15-2005 08:25 AM |
| Unix permissions | moukoko | UNIX for Dummies Questions & Answers | 2 | 03-11-2004 04:12 AM |
|
|
Submit Tools | LinkBack | Thread Tools | Search this Thread | Display Modes |
|
||||
|
Unix File Permissions
Introduction
I have seen some misinformation regarding Unix file permissions. I will try to set the record straight. Take a look at this example of some output from ls: Code:
$ ls -ld /usr/bin /usr/bin/cat drwxrwxr-x 3 root bin 8704 Sep 23 2004 /usr/bin -r-xr-xr-x 1 bin bin 9388 Jul 16 1997 /usr/bin/cat $ How the "File Mode" is stored. On disk, information about a file is stored in structure called an "inode". Each file will have it own inode. One data item in an inode is called the "mode" and it looks like this: Code:
|------file mode------|
| |
|
| |----full-----|
|
|-type| | |--basic--|
| | | | |
oo0 000 000 000 000 000
... ... ... ... ... ...
| | | | |
| | | | |---- rwx for other
| | | |
| | | |-------- rwx for group
| | |
| | |------------ rwx for user
| |
| |---------------- set uid, set gid, sticky bit
|
|---------------------- file type: regular (-)
directory (d)
character special (c)
block special (b)
fifo (p)
symbolic link (l)
socket (s)
Representing those permissions in octal The ls program might display, say, "rwxrwxrwx" for the permissions on a file. It is also very common to use an octal number to express the permissions on a file. And as you see above, this is how they are stored. You may hear someone say that some has 777 permissions. This is the same as "rwxrwxrwx" and much easier to pronounce. So you need to know how to convert them. Three binary digits or bits corresponds to one octal digit: Code:
421 rwx Code:
--- = 0 --x = 1 -w- = 2 -wx = 3 r-- = 4 r-x = 5 rw- = 6 rwx = 7 The Basic Permission Bits We have 3 triples: one triple for the user, one triple for the group, and one triple for other. Sometimes the "user" is called the owner. And sometimes "other" is called "world". I will use "user" and "other" because the chmod command uses the letters u g and o to refer to these triples. Which Set of Bits Applies to You? When Unix decides what you can do, it doesn't use all 9 bits. Unix picks the first triple that applies to you. Consider this: Code:
----rwxrwx 1 joe users 29 Mar 22 19:39 somefile What do r w and x really mean for a file? For a file, "read" and "write" are pretty intuitive. The x for "execute" means that the kernel may attempt to run the file. For that to work, the file must be an executable (output from a compiler) or a shell script with a "#!" first line. For a directory, things are a little more complex. With a directory, "write" permission means that you can create new files in the directory or remove old files. It sometimes surprises people that you can remove a file which you cannot read. The unix rm command will test for that and issue a warning, but you can suppress that warning with -f. And warning or no, if you want to remove an unreadable file from a writable directory, you may. And rmdir will not bother to check at all. What do r w and x really mean for a directory? A directory is a file too, and "read" permission means you can read it. But you really cannot do very much without x permission as well. With directories, you usually have both read and execute permission or neither. On a directory, that x is officially called "search permission". You need x to use a directory in a pathname. So if you try "cat /etc/passwd", you will need x on / and /etc. You also need x to cd into a directory. Suppose you have read but not search (x) permission on a directory. What can you do? Not much. You can use "ls" to view the file names. Even "ls -l" will not work. Read access without search permission is not very useful. Still that is better than having only write permission on a directory...that is completely useless. I have not seen any other documentation that states this explicitly, so let me repeat it: write but no execute permission on a directory grants nothing at all.Suppose you have search (x) permission but no read permission on a directory. Now you can open files in the directory if you happen to know the file's name. You can cd into the directory. And that is it. You cannot even create a new file. Adding write permission will allow you to create files. And you can then delete files if you happen to know their name. Symbolic Links Are Special The permission settings on a symbolic link are a little special as well. They are completely ignored. Many versions of Unix have no way to change them. The Setuid and the Setgid Bits Take a look at this: Code:
$ ls -l /etc/passwd /etc/shadow /usr/bin/passwd -r--r--r-- 1 root sys 14006 Jan 14 11:17 /etc/passwd -r-------- 1 root sys 8281 Jan 14 11:18 /etc/shadow -r-sr-sr-x 3 root sys 96244 Sep 5 2001 /usr/bin/passwd To expand on things a little, while joe is running the suid-to-root passwd program, "joe" is the real uid and "root" is the effective uid. The passwd program can obtain both of these id's if it wants to. This is how the passwd program knows to allow joe to change only joe's password. The Sticky Bit The Posix standard says that if the sticky bit is set on a directory, mere write permission on the directory is no longer enough to allow files to be removed. You must additionally own the file or own the directory. root continues to be able to delete from any directory regardless of permissions. Formerly this bit served another purpose. On some OS's it still does. I will elaborate in an appendix below. The sticky bit affects the "other" execute bit in the ls display. Except that it uses t and T rather than s and S. For example: Code:
drwxrwxrwt 5 root root 1024 Feb 11 20:43 /tmp Limiting File Permissions with umask When files are created the program that creates can specify the initial permission setting. You can override that with umask. The umask is a set of prohibiting bits. There is a umask command that allows you to view and change the umask. For example, "umask 022" prohibits group write and other write on newly created files. Or "umask 027" prohibits group write and it prohibits other read, write, or execute. You can do a "umask 0" to let the program do what it wants as it creates programs. But you cannot go any further. You cannot force a program to turn a bit on. The umask setting affects files, directories, named pipes (aka fifos), and special files. It may or may not affect symbolic links. It also affects somes forms of Inter Process Communication but that is beyond the scope of this article. And believe it or not, named sockets are exempt from umask. This exemption is required by Posix. Changing File Permissions with chmod Only the owner of a file or root can change the permissions on a file. This operation is not affected at all by the umask setting. If you change permissions on a symbolic link, the link will be followed and you will change the target file. It is possible that only root will have the power to set a file's sticky bit. As an example, "chmod 700 somefile" wil let the owner read, write and execute the file, while disallowing all access to any other users. Using Symbolic Mode with chmod and umask Posix introduced a new syntax for the chmod command. The idea was that the new syntax will replace the use of an octal constant with the chmod command. The octal constant is still allowed and I think it's here to stay. But the new symbolic syntax lets you change a few bits without knowing what the others are. For example, let's say that I want to make a file inaccessible to others but I don't what to change the acess for the user or the group. I would need to do: ls -l file Look at file and figure out the current settings. chmod 750 file I had to determine that the first two digits are currents 7 and 5 before I could do my chmod command. With the new syntax, I can simply do: chmod o= file to turn off the final 3 bits. As another example, "chmod u+x file" will allow the user to execute the file. On the other hand, these two commands are equivalent: chmod 750 file chmod u=rwx,g=rx,o= file and I prefer the first syntax. The symbolic mode can be a comma separated list of specifications. Each specification has three components: <who><operation><bitlist> Code:
The who part can be: u (user) g (group) o (other) a (all) (whatever is allowed by umask (subset of all)) The operator can be = or - or + = (set bits to bitlist) - (subtract bitlist from current bit + (add bitllist to current bits) The bitlist can be one of the following letters: r (read permission) w (write permission) x (execute permision) X (conditional execute permision) u (current permissions for user) g (current permissions for group) o (current permissions for others) s (set uid or set gid) t (sticky bit) chmod 6555 /usr/bin/passwd chmod u=rxs,g=rxs,o=rx /usr/bin/passwd chmod ug=rxs,o=rx /usr/bin/passwd chmod a=rx,ug+s /usr/bin/passwd And there are many other ways to do this. For the most part chmod is immune to umask in that whatever bits it wants to set do not get modified by the umask. However, under one condition, the chmod command will examine the current setting of umask to determine which bits it would like to set. This happens when you leave the "who" field blank. Like this: chmod =w somefile The difference between "a=w" and "=w" is subtle. Here is an example that may help. Many programs try to create file with 666 (-rw-rw-rw-) permissions. But this gets modified by the umask. Suppose the you want to set a file to 666 but modified by the current umask. We could turn off all bits, then turn on read and write bits that are allowed by the current umask: chmod a=,=rw somefile And speaking of umask, you can use symbolic arguments with the umask command as well. However, Posix, in their wisdom, decided that in this event to logic would be reversed. So if use umask with an octal argument you specify the bits to be prohibited. But if you use umask with a symbolic argument, you specify the bits to allow. So these are equivalent: umask 022 umask u=rwx,go=rx Summary At this point you have enough information to mostly understand those 12 permission bits. There are several very special cases that I have ignored or glossed over. In separate posts below I will address these. The information in this first post is pretty much universal. A Posix compliant OS must support this stuff. That covers almost all versions of Unix released in the past 10 years. The following articles discuss features that may not be universal. |
| Forum Sponsor | ||
|
|
|
||||
|
The Sticky Bit
I previously have mentioned that when a directory has the sticky bit set, a file can be deleted only by the owner of the file or the owner of the directory. This behavior is specified by Posix and is now rather universal. However that was not the original purpose of the sticky bit. I see that the Posix definition of the ls command actually calls the sticky bit "the restricted deletion flag". The constant in the C header files for this bit is S_ISVTX. The svtx stands for save text and this reveals the original purpose of the bit.
The original idea was that if the sticky bit was set, the text segment of a process would stay in the swap area. This would allow it to be read into memory with a single disk read. Originally, Unix used a filesystem with a block size of 512 and the blocks tended to scatter. So it would take time to collect the text segment and load it into memory. At first there was no paging, only swapping. And to run a program would need to be completely loaded into memory. Now we page-fault a program into memory. Pages are loaded as they are needed. So is the original use of the sticky bit dead? Well, no. It depends on the OS. With HP-UX, this usage is still alive and is documented on the HP-UX chmod(2) man page. What use is this? From The HP-UX Kernel Tuning and Performance Guide via HP-UX Faq: "When applications are located remotely, set the "sticky bit" on the applications binaries, using the chmod +t command. This tells the system to page the text to the local disk. Otherwise, it is "retrieved" across the network. Of course, this would only apply when there is actual paging occurring. More recently, there is a kernel parameter, page_text_to_local, which when set to 1, will tell the kernel to page all NFS executable text pages to local swap space." With Solaris, there is no sign of the original use of the sticky bit, however according to the Solaris chmod(2) man page: "If a regular file is not executable and has S_ISVTX set, the file is assumed to be a swap file. In this case, the system's page cache will not be used to hold the file's data. If the S_ISVTX bit is set on any other file, the results are unspecified." So you will need to check the chmod(2) man page for your particular OS to see what effect, if any, the sticky bit has on a file. Also, be aware that where an effect does exist, the OS may restrict setting a sticky bit to root. For example, with HP-UX, a malicious user could set a lot of sticky bits and run the system out of swap space. HP-UX actually also has some symbolic links that have the sticky bit set. I will address this below. Last edited by Perderabo : 06-04-2005 at 12:09 PM. |
|
||||
|
Enforcement Mode File Locking/Manditory File Locking
We aren't finished with that Set Gid bit yet... Unix has a concept of file locking. File locking is beyond the scope of this thread. But you need to know that file locking comes in two flavors: advisory and manditory. Which flavor applies to a particular file depending on the permission settings. If the group execute bit is off but the setgid bit is on, any file locks on that file are manditory.
Useless Bit Combination? Every reference that I have seen says that setgid on / group execute off is a otherwise useless combination. Even Richard Stevens (in Advanced Programming in the Unix Environment) says "Since the set-group-ID bit makes no sense when the group-execute bit is off, the designers of SVR3 chose this way to specify that the locking for a file is to be maditory locking and not advisory locking." Well consider this case: Fred runs the Human Resources department. Fred and his group often need to lookup the vacation days used for employees. Fred decides to write a program so employees can lookup their own vacation days used. For security, Fred makes this program do a lot of logging. Fred decides that he doesn't want his group to use this program. They have other tools that won't clutter his log. So Fred does: chown fred:hr vdays chmod 2701 vdays Now the vdays program cannot be run by members of hr (except fred). But it can be run by everyone else. And it will assume the gid of hr when it does run. I have written a test program, set it up like this, and have run it on both Solaris and HP-UX. It works. Effect on ls output While this bit combination may be useful is some limited cases, for better or worse, it will have two effects. The vdays program does work, but if a lock is attempted on the file, it will be manditory. As a practical matter, this would impact only an occasional program like a debugger. But ls may treat this bit combination differently. I have seen both of these... Code:
chown fred:hr vdays chmod 2701 vdays -rwx--S--x 1 fred hr 9938 Jul 16 2004 vdays -rwx--l--x 1 fred hr 9938 Jul 16 2004 vdays |
|
||||
|
A Closer Look at the Permission Bits on Symbolic Links
Symbolic links have evolved over the years. At first, a symbolic link was followed only when opening a file. So:
touch datafile ln -s datafile slink chmod 700 slink did not protect the file called "datafile". This was a security problem. Today that "chmod 700 slink" will change the permissions on datafile. "chown fred datafile" will also change datafile and leave slink alone. Symbolic Links Must have an Owner There is a way to change the owner of a symbolic link. It is "chown -h slink". This will change slink and leave datafile alone. The original reason why symbolic links need an owner is a feature called "quotas". Quotas allows the system administration to limit the disk space used by a user. A symbolic link consumes a small amount of disk resources so it must be charged to the appropiate user. We now have a second reason: sticky directories. We need to know who can remove a symbolic link from a sticky directory. In addition to an owner, Posix requires that symbolic link have a size. That is all that you can depend on. Symbolic links may not even have any permission bits. Permission Bits Are Required by Posix to be Ignored On Solaris and Linux, newly created symbolic links are 777 and this is not affected by umask. I could not not find any way to turn the bits off. On HP-UX, symbolic links are also created with 777, but umask does affect this. So: umask 777 ln -s datafile slink creates a symbolic link with all of the bits turns off. This had no effect at all on what I could do with datafile. And symbolic link (with a mode of 0) to directories also worked fine. BSD Has a Way to Change the Permission Bits on a Symbolic Link The various BSD distros all have a "chmod -h" which is like the required "chown -h". Using this command I tested symbolic links on FreeBSD and found that they ignore permission bits as well. The "chmod -h" command is implemented using a lchmod() system call. (BSD even has a lutimes() system call and a "touch -h" command to invoke it.) So far, so good. Nothing here is violating the Posix standard. NetBSD May be Violating the Posix Standard According to the NetBSD symlink man page: "The readlink(2) system call requires read permissions on the symbolic link." readlink() is the system call used by ls to display the target of a symbolic link. So with something like this: Code:
lrwxrwxrwx 1 fred users 8 May 24 11:15 slink -> datafile HP-UX Transition Links When HP rewrote HP-UX to conform to System V Release 4, the location of lots of files changed. As one example, my favorite shell moved from /bin/ksh to /usr/bin/ksh. Some people still use /bin/ksh and that will work (for now) because of a symbolic link: Code:
$ ls -lds /bin 0 lr-xr-xr-t 1 root sys 8 Oct 1 2003 /bin -> /usr/bin But here is what the HP-UX faq has to say: "Transition links are a bit faster, because the linked-to filename is stored in the inode itself, instead of using an allocation unit to store the link." While that statement is not exactly false, it is terribly misleading. HP-UX simply supports fast symlinks. If the referenced file name is short enough, it is stored directly in the inode. The transition links happen to be short enough. I have seen some people use lchmod() to turn on the sticky bit of a symlink in an effort to speed things up. It does not work like that. Transition links are starting to disappear. People who have not switched from /bin/ksh to /usr/bin/ksh may one day get a rude surprise. Below are some links to HP's website. Maintaining Transition Links Transition Links Commands (Deprecated) Transition Links (Deprecated) Last edited by Perderabo : 06-04-2005 at 12:43 PM. |
||||
| Google UNIX.COM |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|