% Unix Modes and Permissions, whoami, id, uid, gid, groups, ls -l, chmod % Ian! D. Allen -- -- [www.idallen.com] % Winter 2016 - January to April 2016 - Updated 2019-03-01 03:58 EST - [Course Home Page] - [Course Outline] - [All Weeks] - [Plain Text] Unix/Linux is a Multi-user system ================================= Unix/Linux has always been a multi-user operating system. (Microsoft Windows didn't become a multi-user operating system until the merge with Windows NT, somewhere around Windows XP?) 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 Unix multi-user system provides security among users and between the system and users. The Unix operating system can protect itself against programs run by ordinary users, so the rare Unix viruses and trojans only affect a single user on a system, not the whole system. > The super-user account `root` on a Unix system can bypass and over-ride all > read/write and access permissions. The super-user can access and do > anything to any inode. In this document, we discuss permissions as they > apply to ordinary, non-`root` users. Users: one user ID and multiple group IDs ========================================= Each logged-in Unix user is assigned one unique numeric user ID and one or more numeric group IDs. (Group IDs may be shared with other users.) The unique user ID and each group ID are internally stored as numbers. Password file: `/etc/passwd`   Group file: `/etc/group` ------------------------------------------------------- The password file and the group file are used to map the numbers to human-friendly names. > The password file `/etc/passwd` maps a user ID number to a name. The group > file `/etc/group` maps each group ID number to a name. The name is a > convenience for people; the processes calculate permissions based on the > numeric IDs. > > User IDs may also be known as **userids** or **uids**. Group IDs may also > be known as **groupids** or **gids**. > > You can easily change the name of a user or a group by changing its name in > the password or group files. There are privileged system commands that > safely do this for you, e.g. `usermod` and `groupmod`. At login, the password file looks up your login user ID and determines your numeric user ID and one initial group user ID. The group file then assigns to you your other group IDs (if any). The system then starts up a shell that runs as your unique numeric user ID and also has the permissions of all your numeric group IDs (one or more). Almost all the commands that you run from the shell inherit your user ID and your one or more group IDs. The processes appear to run as "you". Show user IDs and group IDs: `whoami`, `groups`, `id` ----------------------------------------------------- The `whoami` command shows the name of the current user ID, as recorded in the `/etc/passwd` file. The `groups` command shows the names of the groups of the current user or another user, as recorded in the `/etc/group` file: $ whoami idallen $ groups idallen admin $ groups root root bin daemon sys adm disk wheel The `id` command shows both the name and internal number of the user ID and the names and internal numbers of the groups of the current user or another user: $ id uid=777(idallen) gid=777(idallen) groups=777(idallen),120(admin) $ id root uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) The mapping between numbers and names is done by the password and group files. Processes: one user ID and multiple group IDs --------------------------------------------- Each process (including your shell and each command and process that you run from your shell) runs with the permissions of your single numeric user ID and your one or more numeric group IDs. These numbers are assigned to you when you log in and are passed to most commands when you run them. For example, when you execute the `cp` command, the executing `cp` process inherits your numeric user and group IDs from your shell. The `cp` command can only perform actions consistent with permissions granted to your user ID and group(s). If someone else executes the very same `cp` command, their running copy will execute using *their* numeric user and *their* group IDs. > See below for special *setuid* and *setgid* programs that do *not* inherit > your user IDs when you run them. [Appendix: Programs with special > privileges: setuid / setgid] File system inodes have one owner (user ID), only one group =========================================================== File system inodes (e.g. files and directories) are owned by one user ID (the "owner") and belong to only one group (the "group"). (Kernel extensions can expand this restriction.) The owner and group are stored in the inode as internal numbers; the password and group files are used to map the numbers to human-friendly names. The `ls` command uses the password and group files to show you the name of the owner and name of the group for each file system inode (the third and fourth fields in the output below): $ ls -ld / /dev/mem /etc/shadow /home/idallen /var/log/auth.log drwxr-xr-x 26 root root 4096 Oct 26 02:16 / crw-r----- 1 root kmem 1, 1 Oct 26 04:45 /dev/mem -rw-r----- 1 root shadow 46616 Oct 25 21:32 /etc/shadow drwxr-x--x 44 idallen idallen 4096 Oct 27 19:59 /home/idallen -rw-r----- 1 syslog root 52902850 Oct 28 00:41 /var/log/auth.log It is important to know that the owner and group are stored in each inode as numbers, not names. The password and group files are necessary to turn the stored numbers into human-friendly names. Changing an inode owner name or group name ------------------------------------------ Changing a user name or group name in the password or group files (requires `root` privileges) will change the names displayed by `ls`: $ tail -n 1 /etc/group test:x:3234: $ ls -l foo -rw-r--r-- 1 root test 29 Oct 25 07:05 foo $ sudo groupmod -n newtest test # rename group "test" to "newtest" $ tail -n 1 /etc/group newtest:x:3234: $ ls -l foo -rw-r--r-- 1 root newtest 29 Oct 25 07:05 foo Changing the password or group files affects the output of `ls`, because `ls` uses these files to map the internal user ID and group ID numbers in the inodes to human-friendly names. Inode owners and groups with no password or group file names ------------------------------------------------------------ If an internal owner or group number in an inode can't be mapped to a human-friendly name by `ls` (because there is no name for the internal number found in the password or group file), `ls` will simply show the internal number in its output: $ sudo groupdel newtest # delete group "newtest" $ ls -l foo -rw-r--r-- 1 root 3234 29 Oct 25 07:05 foo > You often see numbers in the output of `ls` when you mount an external disk > that comes from some other system -- the internal numbers on that disk > don't correspond to your current password and group files and so many of > the owner and group numbers in the inodes on the external disk won't have > matches, and many of the matches on the external disk may map to incorrect > names. Without the password and group files, there is no way to know the human-friendly names of the owner and group numbers stored in the inodes. Summary: users and processes vs. file system inodes =================================================== You, when you log in, and any process you run, have the permissions of *one* user ID and *one or more* groups simultaneously (many groups): $ id uid=777(idallen) gid=777(idallen) groups=777(idallen),4(admin) 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 user ID and be in exactly *one* Unix group (single group): $ ls -l /etc/passwd -rw-r--r-- 1 root root 2458 Nov 18 01:17 /etc/passwd Processes (run by users) can have many groups; file system inodes can have only one group. Permissions: Match login userid/groups to inode owner/group =========================================================== When a process tries to read or write any kind of file system inode (a file, a directory, or some other file system object), the meshing of the user and group IDs of the process and the owner and group IDs set in the inode determine if the access succeeds. What a process can do to a file system inode -- what permissions it has on the inode -- is determined by how the process user ID and any of its many groups mesh with the single owner/userid and single group ID of the inode in the file system. File system inode permissions: file mode ---------------------------------------- The word **mode** is often used in Unix to talk about the permissions of a file system inode. The term **mode** means "file system inode permissions". We often casually say "file" mode, but permissions apply to each inode whether it is a file, directory, or something else. Using `ls -l` to display the symbolic mode of an inode ------------------------------------------------------ Each file system inode has room in its **mode** to store three sets of three Unix permissions (nine permissions in total). These three sets of three permissions stored in the inode control which processes can read or modify the inode. The three sets are named **user** (owner), **group**, and **other** permissions, abbreviated `u`, `g`, and `o`. Note that **user** permissions are sometimes called **owner** permissions, but the abbreviation is always `u` for **user**. Each set itself contains three possible permissions, named **read**, **write**, and **execute/search**, abbreviated `r`, `w`, and `x`. Note that **search** permission is still abbreviated as `x`. Three sets of three permissions gives a total of **nine** permissions. The `ls` command displays these nine permissions in symbolic form as three sets of three `rwx` letters and/or and dashes near the start of a long listing: $ ls -ld filename dirname symlink -rw-r----- 1 user1 group1 123 Nov 12 14:14 filename drwxr-x--x 1 user2 group2 123 Nov 12 14:14 dirname lrwxrwxrwx 1 root root 123 Nov 12 14:14 symlink -> target The first character in the `ls -ld` listing above is the **type** of the inode (it is not part of the nine permissions). Common **type** character values are: - `-` : a dash/hyphen/minus indicates that the inode is a plain file - `d` : indicates that this inode is a directory - `l` : (lower-case `L`) indicates a symbolic link (permissions are ignored) - There are other characters too; you will learn them later. The **nine** characters after the **type** character are the **Mode** or **Permissions** of the inode. There are three sets of three possible `rwx` permissions, one set of three for each of **user**, **group**, and **other**: - *d*`rwxr-x--x` -- **type** field: `d` is a directory - `d`*rwx*`r-x--x` -- **user** permissions (first three `rwx`) - `drwx`*r-x*`--x` -- **group** permissions (second three `r-x`) - `drwxr-x`*--x* -- **other** permissions (last three `--x`) The three characters in a set are always displayed as three characters, in `rwx` order. In each set of three permission characters, a hyphen/minus/dash character `-` replaces a letter if the corresponding permission is not granted in that set, e.g. - `rwx` means read, write, and execute/search permissions are granted - `rw-` means only read and write permissions are granted - `r--` means only read permission is granted - `--x` means only execute/search permission is granted - `---` means no permissions are granted A hyphen/minus/dash in any of the three positions means NO permission, so `---` means no read, no write, and no execute (no permissions at all) for that type of permission on this file inode. Matching process permissions with inode permissions --------------------------------------------------- Here is what happens when a Unix process (running as some user ID and with some set of group IDs) tries to access a Unix file system inode: 1) **User Permissions**: If the unique user ID of the process doing the access matches the user ID that owns the inode, the three permissions in the **user** (owner) permissions field of the inode determines whether or not the access succeeds. (The user/owner permissions are the first set of three permissions letters in the output of `ls -l`.) If the user IDs do not match, move to part #2: 2) **Group Permissions**: (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 three permissions in the **group** permissions field of the inode 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) **Other Permissions**: (Only done if both the user IDs and group IDs do not match:) The three permissions in 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 user IDs 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 user ID 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. Example: matching three sets of three permissions ------------------------------------------------- Given this file: $ ls -ld filename -rw-r----x 1 user1 group1 123 Nov 12 14:14 filename 1. The first three characters `rw-` of the nine-character mode are the three permissions that apply to any process where the user ID of the process matches the user (owner) of the inode. 2. The second three characters `r--` of the nine are the three permissions that apply to processes where the users do not match but any one of the process group IDs matches the group of the inode. 3. The last three characters `--x` of the nine are the three permissions that apply to everyone else (processes that are not running as the user/owner of the inode and none of the groups match). Above, the file `filename` has mode `rw-` (read, write, NO execute) for user ID `user1`, mode `r--` (read only) for anyone with group ID `group1`, and `--x` (execute only) for everyone else (not `user1` and not in `group1`). The three permissions: `rwx` ============================ In each of the above three sets of permissions -- **user**, **group**, and **other** -- three permissions can be controlled: **Read** permission, **Write** permission, and **eXecute/search** permission. Recall that these three sets of three permissions appear as the letters `rwx` in the output from `ls -l`: $ ls -l /bin/ls -rwxr-xr-x 1 root root 105840 Nov 19 2016 /bin/ls 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: `r--` ---------------------- 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: `-w-` ----------------------- 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: `--x` --------------------------------- 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. Ignore permissions on symbolic links ------------------------------------ One exception to permissions and modes is symbolic links: The permissions on any symbolic link inode are always `rwxrwxrwx` and are always ignored and can't be changed. You can safely ignore the permissions, user, and group of symbolic links. Summary of `rwx` permissions ---------------------------- Each of the three sets of three permissions contains three characters indicating which of these three permissions is allowed for each set: - `r` -- means **read** permission (can access the content of the inode) - `w` -- means **write** permission (can change the content of the inode) - `x` -- means **execute** permission for file inodes and **search** or **access** permission for directory inodes Some important notes on a set of three `rwx` permissions: - A set of permissions is always written down as *three* characters. - The characters are always in `rwx` order, never `wxr` or `xwr` - A permission that is not allowed is shown as a dash or hyphen character (`-`) e.g. `r-x`, `--x`, `r--`, etc., never as `rx`, `x`, or `r`. - Only the `chmod` command allows you to leave out the `-` when changing permissions, e.g. `chmod u=rx` - Ignore all permissions on symbolic links; they mean nothing. Execute/Search permission for directories ========================================= For a directory, execute `x` permission is **search** or **access** permission and it means a process may "pass through" or "access" the directory to access the inode numbers and content of the items named in the directory. 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 (unless your brand of Linux caches that information in the directory), 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` that requires access to the inodes of the items in the directory to find out what kinds of things they are and other information: $ 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 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.) $ cat dir/date Tue Oct 25 11:07:42 EDT 2016 $ ls dir ls: cannot access dir: Permission denied A directory with `-wx` permissions lets a process enter or change names in it; but, without read permissions, 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, remove, or change names in the directory. (You do not also need execute permission to write on a *file*. For a file, write permission is *all* you need to write on it.) Names are separate from content =============================== The permissions that govern *access* to the things listed a directory are stored in the inode for that directory. Without access permissions on a directory, you can't access anything inside that directory. The permissions for the actual items *named* in the directory are *not* kept in the directory. The permissions on the things 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 contents the actual things being named. Changing the permissions of a directory only affects what you can do to the name of the thing stored directory; it doesn't directly affect what you can do to the actual content of 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). Names of things are stored in directories; directories have separate permissions from the things being names. 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 inodes that are named in that directory. (The permissions on the directory itself may prevent some process from getting to an inode using that directory; but, once the process gets to the inode, it is the permissions stored in that inode that apply. No permissions on that inode are stored up in the directory itself.) To determine what access permissions a process has on 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 up 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: `/etc/passwd` ---------------------- 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=777(idallen) gid=777(idallen) groups=777(idallen),120(admin) The current login user ID `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. Changing Permissions using `chmod` ================================== The owner of an inode is the only one who can change the mode (permissions) of an inode. The owner can *always* change the mode of the inode, even if the inode has no permissions for the owner. (So the owner of an inode can always restore full permissions to access the inode.) **Only** the user/owner of an inode can change its permissions, even if the inode has full permissions for other groups or other users. Nobody can change the mode except the owner of the inode. Use the `chmod` (change mode) command to change the permissions (RTFM): chmod mode pathnames... You must supply at least two arguments: 1. one permission ("mode") argument (that may contain multiple permissions) and 2. one or more pathnames of inodes for which the access permissions are to be set or modified Examples of setting or adding/removing permissions on a pathname: chmod u=rwx,g=rx,o=wx path # set inode to rwxr-x-wx or 753 octal chmod 753 path # set to 753 or rwxr-x-wx symbolic chmod u+r path # add only owner read permission; leave wx unchanged chmod go-wx path # remove only group and other wx permissions; leave r unchanged The mode argument can be either octal-numeric or symbolic, as shown above. For an explanation of octal-numeric modes, see [octal permissions]. The `chmod` command *follows* symbolic links given on the command line and changes the *target* that the link points to. It never changes the permissions on the symlink itself. Adding or Removing Permissions using symbolic `+` or `-` -------------------------------------------------------- Note that *adding* or *removing* permissions using symbolic permissions with the `+` or `-` operators (e.g. `u+r`, `go-rx`) *leaves the other unspecified permissions unchanged*. Adding and removing permissions only works for **symbolic** permissions and only affects the given permissions and doesn't change any of the other unspecified permissions. Octal/numeric permissions always set all nine of the permissions; you can't leave any unchanged. Symbolic permissions set with `=` also change all of the permissions; you can't use `=` to add or remove permissions. Adding and removing permissions using the symbolic `+` or `-` operators (e.g. `u+r`, `go-rx`) is very common, since usually you don't want to set or change any of the other existing permissions. For example, to add *other* read permission to all non-hidden inodes in the current directory, use `chmod o+r *` not `chmod o=r *` because the latter would take away existing `w` or `x` permissions, which would make a directory inaccessible. File system damage to directories ================================= 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. Permissions are not affected. Hard links and permissions ========================== 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 a name for an existing inode (`ln`), renaming (`mv`), or removing a name (a hard link) (`rm`) are all directory operations. 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. > Recent versions of the Linux kernel (since 3.6) have created a new kernel > security option that, when enabled, prevents you from making a hard link to > (new name for) a file that you do not own and cannot read or write. See the > kernel `sysctl` option `fs.protected_hardlinks` or entry > `/proc/sys/fs/protected_hardlinks` in the man page `proc(5)`. This Linux > course assumes that this option is *not* enabled, so that you can create a > hard link to any file you can access in the current file system without > restriction. Permissions for using `ls` on the current directory: `ls .` =========================================================== What permissions are needed to list the contents of the current directory (i.e. using `ls` that really means `ls .`)? The current directory is only accessible using the name dot ("`.`"). To get a listing of the contents of the current directory, you must first have permission to use the name dot `.` in the current directory to get to the current directory. The name dot `.` 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 dot `.` in the current directory. Once you have used dot `.` 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 dot `.`) and read permissions (to get a list of the names in the directory). Result -- you need: `r-x` permissions to get the listing. Without search permissions, you cannot use the name dot ("`.`"). 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 idallen idallen 4096 2016-02-29 05:21 new $ touch new/{a,b,c} $ cd new $ ls a b c $ chmod u-x . # remove search permission; leave read perms $ ls ls: cannot open directory .: Permission denied $ ls .. ls: cannot access ..: Permission denied $ ls /home/idallen/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 dot `.` inside the directory to get to the directory. In other words: To see the names in a directory from inside the directory means the directory needs `r-x` permissions; to see the same thing using an absolute path to the directory needs only `r--` permissions on 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 to read the names. 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 "search" or "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. Permission matching exercises ============================= Given the following inode permissions on these things: ---x------ 1 dar staff 123 Apr 1 2016 dar1 ----rwxrwx 1 dar cst8207 512 Apr 1 2016 dar2 dr---wx-w- 1 dar cst8207 512 Apr 1 2016 dar3 -r---wx-w- 1 les cst8207 123 Apr 1 2016 les1 drwxrw-r-x 1 les alumni 512 Apr 1 2016 les2 -rwxrw-r-x 1 pat alumni 123 Apr 1 2016 pat1 d--x------ 1 pat staff 512 Apr 1 2016 pat2 -rw-r--r-- 1 root system 123 Apr 1 2016 root1 drwx----wx 1 root system 512 Apr 1 2016 root2 And given these users and their user IDs and group IDs: root - super user dar - in groups "alumni" and "cst8207" les - in groups "alumni" and "staff" pat - in groups "student" and "cst8207" 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 thing above? (directory, file, other...) 2. For files, 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? e) can the user rename the file? (trick question) 3. For directories, 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? e) can the user rename the directory? (trick question) Selected Answers ---------------- - User `dar` has no permissions on file `dar2`, because user `dar` matches inode owner `dar` and owner permissions are `---`. Because the user/owner permissions match, the system does not try group or other permissions. - User `dar` can only read the names in directory `dar3`, because user `dar` matches inode owner `dar` and owner permissions are `r--`. Because the user/owner permissions match, the system does not try group or other permissions. - We don't know if any of the files or directories listed above can be renamed, because the names for the things above are stored in some directory whose permissions we aren't given. We only see the permissions of the things *inside* the directory, not the permissions of the directory inode that contains the above names. The answer to this trick question is "not enough information to answer". Appendix: Programs with special privileges: setuid / setgid =========================================================== Normally when you execute a program, the program inherits your user ID and your group IDs from your shell and the program runs "as you" and has your permissions. A very few program executable files are set up on Unix to execute using the user ID and/or group ID of the file inode of the program; they do not inherit from 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 or modify files in directories where ordinary users cannot write. They also may need special permissions to access network resources. Setuid and setgid programs show up with the `s` bit set (instead of `x`) in the owner and/or group permissions field in the output of a `ls -l` listing: $ ls -l /bin/su /bin/ping /bin/umount /bin/mount -rwsr-xr-x root root 36832 Sep 12 2016 /bin/su -rwsr-xr-x root root 35712 Nov 8 2016 /bin/ping -rwsr-xr-x root root 69096 Mar 30 2016 /bin/umount -rwsr-xr-x root root 94792 Mar 30 2016 /bin/mount The above **setuid** programs (`rws`) do not take on the user ID of the person who runs them; the programs always run with the privileges of the `root` account that is the owner of the file inode. $ ls -l /sbin/unix_chkpwd -rwxr-sr-x 1 root shadow 35432 Feb 8 2016 unix_chkpwd The above **setgid** program (`r-s`) does not take on the group ID of the person who runs it; the program always runs with the group privileges of the `shadow` group account that is the group of the file. $ ls -l /usr/bin/at -rwsr-sr-x 1 daemon daemon 51464 Jan 14 2016 /usr/bin/at The above program is both **setuid** (`rws`) *and* **setgid** (`r-s`). It runs with the privileges of user ID `daemon` and group ID `daemon`. Only the owner of an inode can change its mode (permissions), and that includes making its 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. Appendix: Resources and Links ============================= - -- | Ian! D. Allen, BA, MMath - 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/ [Plain Text] - plain text version of this page in [Pandoc Markdown] format [www.idallen.com]: http://www.idallen.com/ [Course Home Page]: .. [Course Outline]: course_outline.pdf [All Weeks]: indexcgi.cgi [Plain Text]: 500_permissions.txt [Appendix: Programs with special privileges: setuid / setgid]: #appendix-programs-with-special-privileges-setuid-setgid [octal permissions]: 510_umask.html [Pandoc Markdown]: http://johnmacfarlane.net/pandoc/