========================== Unix Modes and Permissions ========================== -Ian! D. Allen - idallen@idallen.ca - www.idallen.com Unix is a multi-user system. Each process/program runs as one user with multiple group permissions. File system objects (e.g. files and directories) are owned by one user and belong to one group. The matching of process userids and groups with file system userids and groups determines who can do what to a file system object. Processes belonging to different users have restrictions on how they can interact with each other and with the file system. Files belong to different users, and users can control how processes run by themselves and other users access their files. The system provides security among users and between the system and users. This means Unix can protect itself against programs run by ordinary users. ------------------------------------ Processes: Unix user ID and group ID ------------------------------------ Each Unix process (including your shell and each command and process that you run from your shell) runs with the permissions of a single numeric user ID. Each process also runs with the permissions of one or more numeric group IDs. The single numeric user ID and multiple group IDs also have names; the Unix password file /etc/passwd maps the user ID number to a name; the file /etc/group matches each group ID number to a name. The name is a convenience for people; the processes calculate permissions based on the numerid IDs. The command "id" shows these numbers and names: $ id uid=500(idallen) gid=500(idallen) groups=500(idallen) $ id root uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) When you log in, the system starts up a shell that runs as your unique numeric user ID and has the permissions of all your numeric group IDs (one or more). Almost all the commands that you run inherit your user ID and your one or more group IDs. The processes appear to run as "you". For example, when you execute the "cp" command, the executing process runs with your numeric user and group IDs. The "cp" command can only perform actions consistent with permissions granted to your userid and group. If someone else executes the very same "cp" command, their copy will execute using their numeric user and group IDs and have different permissions. -------------------------------------------------- Setuid / Setgid - programs with special privileges -------------------------------------------------- Normally when you execute a program the program runs using your userid and group IDs. A very few program executable files are set up on Unix to execute using the user ID and/or group ID of the program file itself, not the person running the program. These program files are called either "setuid" (set user ID) or "setgid" (set group ID) programs. Typically, these are privileged programs that need to create files in directories where ordinary users cannot write. They also may need special permissions to access network resources. Only the owner of a file can make the program file setuid or setgid. A poorly written setuid file may be a security problem. With its elevated privileges, the setuid file may be exploited to damage the system. Looking for unusual setuid programs is part of a system security check. Setuid programs show up with the "s" bit set in an "ls -l" listing: $ ls -l /sbin/ | grep 'rws' -rwsr-xr-x. 1 root root 116224 2009-11-02 17:40 mount.nfs -rwsr-xr-x. 1 root root 7668 2009-11-02 04:20 pam_timestamp_check -rwsr-xr-x. 1 root root 30700 2009-11-02 04:20 unix_chkpwd ----------------------------------------------- Unix file system IDs - only one uid and one gid ----------------------------------------------- Recall that running processes may be have the permissions of one userid and *many* groups simultaneously: $ id uid=777(idallen) gid=777(idallen) groups=777(idallen),4(adm),6(disk) In the Unix file system, each inode, whether it is a file inode, a directory inode, or some other kind of inode, can be "owned" by exactly one Unix userid and be in exactly *one* Unix group: $ ls -l /etc/passwd -rw-r--r-- 1 root root 2209 Jan 19 20:39 /etc/passwd Processes can have many groups; file system objects can have only one. ----------------------------------- Determining which permissions apply ----------------------------------- When a Unix process tries to access any kind of Unix file system inode (a file, a directory, or some other file system object), the meshing of the permissions of the process and the inode determine if the access succeeds. Each file system inode has room to store three sets of Unix permissions: "user", "group", and "other" permissions. The "ls" command displays these as three sets of three letters ("rwxrwxrwx") at the start of a long listing. Here is what happens when a Unix process (running as some user and some set of groups) tries to access a Unix file system inode: 1) If the unique user ID of the process doing the access matches the user ID that owns the inode, the "user/owner" permissions field of the inode determines whether or not the access succeeds. (The user/owner permissions are the first three permissions letters in the output of "ls -l".) If the user IDs do not match, move to part #2: 2) (Only done if the user IDs do not match:) If any of the several group IDs of the process doing the access match the single group ID of the inode, the "group" permissions field determines whether or not the access succeeds. (The group permissions are the second set of three permissions letters in the output of "ls -l".) If the group IDs do not match, move to part #3: 3) (Only done if both the user IDs and group IDs do not match:) The "other" permissions field determines whether or not the access succeeds. (The other permissions are the last [rightmost] set of three permissions letters in the output of "ls -l".) Note that if the userids match, those are the *only* permissions used, even if those permissions deny access. The same applies to a group match. It is *not* true that the system will try group or other permissions if the userid or group permissions deny access. Once a set of permissions is chosen, they are the only permissions used. Yes, you can create inodes where the owner can't read the data but everyone else can. Only the owner of an inode (file, directory, etc.) may change its permissions. (Only the owner can enable/disable access by user/owner, group, or other.) -------------------------- The three permissions: rwx -------------------------- Three permissions can be controlled in each of the above three cases: Read permission, Write permission, and eXecute/search permission. These appear as the letters "rwx" in the output from "ls -l": $ ls -l /bin/ls -rwxr-xr-x 1 root root 105776 Feb 23 2011 /bin/ls The first character in the "ls" listing is the type of the inode. (A dash indicates it is a plain file.) The next nine characters are the "rwx" permissions that apply to each of "user", "group", and "other". The user ID and group ID(s) of the process are matched against the user ID and group ID of the inode to determine which of the three sets of permissions apply: "user", "group", or "other". Once a set is chosen, the "rwx" permissions are used to limit what the process can do to that inode: Read Permission: The process can read the data in the inode. For a file, the process can read the data contained in the file. For a directory, the process can read only the names contained in the directory. Read permission on a directory *only* gives the process access to the names in the directory itself. (The process needs further permission to follow the inode numbers to have access to the actual inodes and content of the items named in the directory. You may be able to see a file's name but not have permission to see the file's owner or contents.) Write Permission: The process can write to the inode. For a file, this means that the process can alter the data contained in the file. For a directory (which only contains names and inode numbers), the process can add, remove, or alter (rename) the names in the directory. Write permission on a directory *only* gives the process the ability to change the *names* in the directory. (The process may not have permission to alter the data in the inodes of the items named in the directory. You may be able to rename or delete a file name but not have permissions to read or write the file data itself.) eXecute/Search Permissions: For a file, the process may load the binary image of the file into memory and execute it. If the file is executable but not binary, i.e. a script file, it is the program specified in the "#!" line at the top of the script file that is loaded into memory instead. For a directory, the process may "pass through" the directory to access the inode numbers and content of the items named in the directory. Without search permissions on a directory, the process cannot access any of the inodes and content named in the directory. --------------------------------- Search permission for directories --------------------------------- If you have only "r--" permissions on a directory (only read permissions), you can only see the names in the directory; you cannot "pass through" the directory to the inodes of the things named in the directory. You cannot find out the kind of things to which the names are attached, nor can you access the content of those things. You only have permission to see the names in the directory, not to use them. "ls" works, but not "ls -l" (which requires access to the inodes of the items in the directory to find out what kinds of things they are and other information). If you have only "--x" permissions on a directory (only search permissions), you can "pass through" the directory to the inodes of anything contained in the directory; but, you cannot read any of the names in the directory. You have permissions to use the names, not to see them. (Of course, the only way you can use a name that you can't see is if you already know that the name is in the directory.) A directory with "-wx" permissions lets a process enter names into it; but, the process cannot read the names back from the directory. (If the names are random and guaranteed unique, it's a form of digital "drop box" where items can be created and written by any process but whose names cannot be snooped by other processes.) A directory with only "-w-" permissions is useless, though you might think it would permit you to create new names or to rename existing names if you know them. The implementation is such that any action that requires write permission on a directory also requires search permission. (Consider that any action that writes a name in a directory also has to have access to the inode of the thing being named, and that inode access requires search permissions on the directory.) Similarly, having "rw-" permissions is the same as "r--" permissions; without search permissions, write permissions don't work. You need search permission as well as write permission on a directory to be able to create or remove names in the directory. ------------------------------- Names are separate from content ------------------------------- The permissions that govern access to a directory are stored in the inode for that directory. The permissions for the items *named* in the directory are *not* kept in the directory; they are stored in the inodes for the items being named. Because names are stored separately from the things they name, the permissions you may have to alter the names in the directory are *not* the same as the permissions you have to alter the actual things being named. Changing the permissions of a directory only affects what you can do to the directory; it doesn't directly affect what you can do to the things named in the directory. You may be able to write the inode of the directory but unable to write the inodes of anything named in the directory, or vice-versa. You may have a directory that you can modify ("rwx") that contains names for things that you cannot even read ("---"). You can rename the things or remove their names from your directory; but, you cannot read the things or change them in any way. You may have a directory that you cannot modify ("r-x") that contains names for things that you have full permissions to modify ("rw-"). You have full permissions to modify the item named in the directory; but, you cannot remove its name from the directory or change its name (because you cannot write the directory where the name is kept). ------------------------------------------ Unix directories are only names and inodes ------------------------------------------ Unix directories are very simple; they only contain names and inode numbers. Nothing in a directory directly controls what access permissions a process has to Unix file system objects that are named in that directory. (The permissions on the directory itself may prevent some process from getting to an object using that directory; but, once the process gets to the object, it is the permissions stored in that object's inode that apply. No object permissions are stored in the directory itself.) To determine what access permissions a process has with respect to some Unix file system object, the process must use the object's name to pass through the directory and go to the actual inode for the object. Permissions for the object (e.g. a file) are not kept in the directory; they are kept in the inode for the object. Only the object's name and inode number are kept in the directory. The inode containing the permissions for an object is separate from the directory inode containing the name of the object. To access an object, a process needs to pass through the directory (it must have "search permission" on the directory inode) and then have appropriate permissions on the inode that is the object itself. Example: The pathname /etc/passwd refers to two directories and one file. To know how your account and groups can access this file, you need to look at the permissions on the two directories and on the file itself: $ ls -ld / drwxr-xr-x 24 root root 4096 Nov 24 16:51 / $ ls -ld /etc drwxr-xr-x 180 root root 12288 Feb 29 13:38 /etc $ ls -l /etc/passwd -rw-r--r-- 1 root root 2209 Jan 19 20:39 /etc/passwd $ id uid=500(idallen) gid=500(idallen) groups=500(idallen) The current login userid "idallen" and the current group "idallen" do not match the owner or group of ROOT, /etc, or /etc/passwd, which means that "other" permissions apply to both directories and to the file itself: 1. The "r-x" permissions on ROOT allow /etc to be reached (search ok). 2. The "r-x" permissions on /etc allow /etc/passwd to be reached (search ok). 3. The "r--" permissions on /etc/passwd allow the content to be read. One could prevent access to this file by removing "other" permissions from any of the three inodes in the pathname. (Removing permissions from the ROOT or /etc directories would prevent access to huge numbers of other files and directories and may prevent the system from working properly!) Summary: All the directories leading to a pathname need to have search permissions enabled. The permissions on the final pathname component (the basename) must allow the desired access. ------------------ File system damage ------------------ When a file system is damaged and a directory inode is lost, the only things that go missing are the names of the items in the directory. Everything else about the items - the permissions, owner, group, modify time, size, etc. - is not lost; it is stored in the items' inodes, separate from the lost directory inode. A damaged directory only loses names, not data. ---------- Hard links ---------- When you create a hard link to a file, you create another name in a directory for the file's unique inode number. Since the file permissions are stored with the file's inode, not in the directory, all the names for a file lead to the same inode and thus to the same permissions. Changing the permissions of a file using one of the hard-linked names changes the permissions for the inode and thus for all the names; all the names lead to the same unique inode and the same permissions. Hard-linked names cannot have different owners, groups, or permissions; both names lead to the same inode. Creating, renaming, or removing a name (a hard link) is a directory operation. The permissions on the directory inode apply, not the permissions on the inode of the thing to which you are making a link. You can create in your own directory a hard link to a file even if you have no permissions to read the file itself. You can remove or rename the name of a file in your directory if you have permission on the directory; you don't need any permissions at all on the inode of the file itself. ----------------------------------- Using "ls" on the current directory ----------------------------------- What permissions are needed to list the contents of the current directory (i.e. "ls" which really means "ls .")? The current directory is only accessible using the name ".". To get a listing of the contents of the current directory, you must first have permission to use the name "." to get to the current directory. The name "." is itself stored in the current directory. To use ("pass through to") any name in a directory, you must have search permissions on the directory; so, you must have at least "--x" permission on the current directory to *use* the name "." in the current directory. Once you have used "." to get to the inode that is the current directory, you must be able to read the names from the directory to generate a listing of its contents for "ls". Reading the names in a directory requires at least read permission on the directory ("r--"). Thus, to get a listing of the current directory, on the directory you must have both search permissions (to use the name ".") and read permissions (to get a list of the names in the directory). Result - you need: "r-x" Without search permissions, you cannot use the name ".". Without read permissions, you cannot get a list of the names in the directory. You need both. $ pwd /home/idallen $ mkdir new $ ls -l new total 0 $ ls -ld new drwxrwxr-x. 2 alleni alleni 4096 2012-02-29 05:21 new $ touch new/{a,b,c} $ cd new $ ls a b c $ chmod u-x . $ ls ls: cannot open directory .: Permission denied $ ls .. ls: cannot access ..: Permission denied $ ls /home/alleni/new a b c $ chmod u+x . chmod: cannot access `.': Permission denied $ chmod u+x /home/idallen/new $ ls a b c If you use the absolute pathname of the directory, you only need read permissions on a directory to see the names in it, because you are not needing to use the name "." inside the directory. ------------------------------------- Long listings need search permissions ------------------------------------- What permissions are set on directory "dir", below? $ unalias ls $ ls dir x y z $ ls -l dir ls: cannot access dir/x: Permission denied ls: cannot access dir/z: Permission denied ls: cannot access dir/y: Permission denied total 0 -????????? ? ? ? ? ? x -????????? ? ? ? ? ? y -????????? ? ? ? ? ? z Answer: Read permissions but not search (eXecute) permissions. The "ls" command without any options simply lists the names in the directory. This only requires read permissions on the directory. The simple "ls" with no options succeeded; the directory had read permissions. With the "-l" option, "ls -l" must use each name in the directory to access the inode associated with that name to find out the permissions, owner, group, times, etc. for that inode. To use a name - to "pass through" a directory - requires search (eXecute) permissions on the directory, which were not enabled. For each name in the directory, the permission to access "dir/name" for the long listing was denied. The directory had read permissions but no search permissions. We can see the names, but we are not allowed to use the names to find out anything about the objects being named. NOTE: Careful observers will note that the "ls -l" command did know the file inode type of each of the files - the first character in each line of output is a dash, not a question mark. Modern Unix/Linux systems cache some of the inode information in the directory so that commands such as "ls" don't have to make a disk access every time just to find out what kind of inode each name is. --------- Exercises --------- Given the following inode permissions: ---x------ 1 dar staff 123 Apr 1 2012 dar1 dr---wx-w- 1 dar dat2330 512 Apr 1 2012 dar2 -r---wx-w- 1 les dat2330 123 Apr 1 2012 les1 drwxrw-r-x 1 les alumni 512 Apr 1 2012 les2 -rwxrw-r-x 1 pat alumni 123 Apr 1 2012 pat1 d--x------ 1 pat staff 512 Apr 1 2012 pat2 -rw-r--r-- 1 root system 123 Apr 1 2012 root1 drwx----wx 1 root system 512 Apr 1 2012 root2 And these users: root - super user pat - in groups "student" and "dat2330" les - in groups "alumni" and "staff" dar - in groups "alumni" and "dat2330" kai - in groups "alumni" and "system" tam - in groups "system" and "staff" dod - in groups "nobody" Answer these questions: 1. What type of inode is each file? (directory, file, other...) 2. What permissions do each of the users have on each file inode? a) which set of permissions apply to each user? b) can the user read the file? c) can the user write the file? d) can the user execute the file? 3. What permissions do each of the users have on each directory inode? a) which set of permissions apply to each user? b) can the user read the directory names? c) can write the directory (create new names, delete names, rename)? d) can search (pass through) the directory to the contained inodes? -- | Ian! D. Allen - idallen@idallen.ca - Ottawa, Ontario, Canada | Home Page: http://idallen.com/ Contact Improv: http://contactimprov.ca/ | College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/ | Defend digital freedom: http://eff.org/ and have fun: http://fools.ca/