High-Level Filesystem: Permissions
Let's look at how directories and files are protected from unauthorized access.
Basic Permissions—The Unix Model
On a Unix system, each file and directory has an owner and a group. The owner is the user who created the file (but can be changed to some other user later), and the group is a collection of users who share access to the file or directory. (Unix systems have a global groups list that maps group names to a group ID and a list of users who are members of the group). Each file also has three sets of permissions: one for the owner, one for the group, and one for everyone else.
Permissions are (of course), a bit more complex than we're discussing here. Run
man chmodto see lots more fiddly details.
Permissions themselves are divided into three categories:
- Read: allows a user to view the contents of a file or directory
- Write: allows a user to modify the contents of a file or directory
- Execute: allows a user to run a file or access the contents of a directory.
When you list the contents of a directory with ls -l, you'll see a string of ten characters at the beginning of each line. The first character indicates the type of file (regular file, directory, symbolic link, etc.). The next three characters represent the owner's permissions, the next three represent the group's permissions, and the last three represent everyone else's permissions.
Notice that leading zero? That's a detail we're leaving out here.
Thus, if a line starts with -rwxr-xr--, the file is a regular file with read, write, and execute permissions for the owner, read and execute permissions for the group, and read-only permissions for everyone else. These permissions can be represented as a bit string, where each permission is a bit that is set to 1 if the permission is granted and 0 if it is not. For example, the permissions -rwxr-xr-- can be represented as 0111101100. In octal, each octal digit is three bits, so the permissions can be represented as 111 101 100, which is 7 5 4 in octal. Thus, 0666 is read/write for everyone, 0755 is read/write/execute for the owner and read/execute for everyone else, and 0644 is read/write for the owner and read-only for everyone else. Similarly, a file set to 0600 will be read/right only for the owner; 0700 read/write/executable or listable if a directory; 0660 read/write for owner and group, but not for anyone else. You'll see these constants used a lot in calls to open in C programs.
You can also use octal permissions with the
chmodcommand. You don't have to, but you can. For example,chmod 755 filesets the permissions offiletorwxr-xr-x.
But you can also just say
chmod u+x fileto add execute permission for the owner (a.k.a. user who owns the file), orchmod go-w fileto remove write permission for the group and others. That is so much easier to remember!
What if you want a file to be accessible to MORE than one group? Does it have to be accessible to everyone?
In the classic Unix model, a file can only belong to one group. You could make a new group that combines the users from the two groups, but that's a bit of a hassle.
Meh. Good enough. Worse is better and all that.
Access Control Lists
The Unix model is simple and effective, but it has some clear limitations. For example, a resource can't belong to more than one group. To address these limitations, some systems use an additional level of permissions called access control lists (ACLs). An ACL is a list of permissions that can be associated with a file or directory. Each entry in the list specifies a user or group and the permissions that user or group has. In addition, the actions allowed on files and directories are broken down into more fine-grained permissions, such as being able to extend a file with new data but not modify what's already there, or controlling exactly which actions can be performed on a directory (e.g., you can add files, but you can't delete files or create subdirectories).
ACLs typically have a scope that usually corresponds to the directory hierarchy. For example, if an upper-level directory is protected by an ACL, all the files and directories within it are also protected by that ACL, so you don't need to set an ACL for each file).
Today's Unix-like systems, including macOS and Linux provide ACL facilities. Some other examples of ACL-based systems include Novell NetWare, which created an LDAP-like directory for managing users and permissions. Novell's model was later imitated by Microsoft's Active Directory.
Role-Based Access Control
While many groups of users can easily get by with simple Unix-style permissions or ACLs (e.g., on their personal laptop or a small shared server), more complex systems often require (or desire) more sophisticated and granular access controls.
Role-based access-control systems define “roles” that have sets of permissions assigned to them; for example, personal or group directories or file shares; sets of machines; or access to printers or other hardware assets. Users can be assigned one or more roles, and have a complex set of access rights granted without requiring each resource to be individually granted or withheld. These systems also make it easier to change permissions if, for example, someone transfers from one department to another, or one location to another, and they're easy to revoke in the case of someone leaving the organization.
If you're logging in to a computer that's part of a larger system, what you can and can't do is probably determined by some complex set of rules dictated by organizational or business goals and requirements, and maintained by the system's administrators.
Wow. That all seems incredibly complicated.
Meh. I bet it was all invented in the 1980s. Good thing we don't have to implement this stuff.
A lot of these ideas can be traced back even further; for example, starting in 1964, MULTICS was planned to incorporate hierarchical filesystems and ACLs, with working implementations in the early 1970s. Additional frameworks supporting mandatory access control were added in mid-1970s.
(When logged in, completion status appears here.)