Linux Permissions and Extended ACLs

Linux Permissions and Extended ACLs

At Teknophiles, we love the speed and flexibility of Linux.  We also love Linux servers’ streamlined and utilitarian nature.  When coming from a Windows background, however, you may find some areas where you miss the ease of management the Windows operating system offers.  One aspect that we typically find somewhat lacking in Linux is the out-of-the-box permission management in most file systems.

Traditional Unix Permissions

While simple and straightforward, traditional Unix permissions leave a bit to be desired at times.  In this model, each file or directory’s permissions are broken into three broad categories – user (owner), group, and other (world).  The owner is assigned one set of permissions, while the group is assigned a different set of permissions.  All users that are not either the owner or a member of the specified group are covered by the “other” permissions.  Permissions in their most basic form are defined as read (r), write (w), execute (x), or any combination of these three.  For example, if the owner of a file has rwx permissions, they are said to have read, write, and execute permissions.  If the group has r-x permissions they are said to have read and execute only.

A file or directory’s permissions can be neatly displayed by listing the contents of a directory in Linux using the ls command.

This output can be divided into 8 columns as shown here:


Each column represents the following:

  1. Directory (d) or regular file (-) notation
  2. The Unix permission set
  3. The number of links (hard links for files, sub-directories for directories)
  4. The user (owner)
  5. The group
  6. The file or directory size in bytes
  7. The date/timstamp
  8. The file or directory name

The Unix permissions (2) can be further broken down:

  • Positions 1-3 – User (Owner) Permissions
  • Positions 4-6 – Group Permissions
  • Positions 4-9 – Other (World) Permissions

Using our example above, we can see that files/ is a directory, and the owner of the directory is user1 and the group is group1.  The directory (not its contents) is 4KB in size and was last modified on October 17th of this year.  Looking at the Unix permissions, we can see that the owner has read, write and execute permissions.  The group also has read, write and execute permissions, while all other users have no access to the directory.

Changing permissions on a file is primarily performed by executing three commands – chown, chgroup, and chmod.  The chown command changes the file’s owner and takes the basic form: chown [OWNER] [FILE] as shown here:

Similarly, the chgroup command changes the file’s group:

These two commands can be combined and simplified as follows:

Changing a file’s permissions is a bit more complicated, and there are two methods for doing so, symbolic mode and numeric mode.  Symbolic mode is a bit more intuitive, but not quite as succinct as numeric mode.  The chmod command in symbolic mode takes the basic form, chmod [ugoa] [-+=] [FILE], where:

u = user
g = group
o = other
a = all


– removes the permission
+ adds the permission
= assigns the permission

For instance, if we wanted to give all users read, write and execute permissions, we could use this command:

Now to remove the write permission from other:

To change a file’s permissions in numeric mode, you must use the chmod command to specify a three-digit number, with each digit assigned a value of 0-7.  The first digit in the three-digit number specifies the owner permissions, the second digit specifies the group permissions, while the third digit specifies the other permissions.  Subsequently, each digit is calculated by adding the values of each bit in the rwx designation.  The values are assigned to each permission as follows:

r   w x  –
4  2  1  0

Thus, rwx corresponds to a value of 7 (4+2+1), while r-x corresponds to a value of 5 (4+0+1) and rw- a value 6 (4+2+0).

This may be hard to visualize, so let’s repeat the previous exercise and give all users read, write and execute permissions as before.  To do this using the chmod command in numeric mode, it would look like this:

The first seven grants rwx (4+2+1) to the owner, the second seven grants the group rwx (4+2+1) permissions and the third seven grants rwx (4+2+1) to everyone else.  And to remove all permissions for other, we simply reissue the command with different chmod values:

The first two values work just as before.  The final zero is the symbolic equivalent of – – – or no access to this file.

Extended ACLs

But now let’s consider a scenario in which we want to implement more complex permissions.  This is where traditional Unix permissions tend to fall short.  With traditional Unix permissions, you cannot for instance, add multiple groups or users to a file or directory.  This becomes increasingly troublesome if you intend to use your Linux box as a file server in a Windows environment.  Fortunately, Linux offers an extended ACLs package that solves this problem, called acl.  Extended ACLs offer a full set of permissions that allows us to apply permissions and even inheritance with nearly the same ease we’re used to on a Windows file server.

Install the extended ACLs as follows:

The package is comprised of two main components – getfacl and setfacl.  The getfacl command retrieves the ACLs on a folder or file, while setfacl adds, modifies or removes ACLs.  Before we modify any permissions, however, let’s take a look at the same directory called files with getfacl:

As we can see from this example, the output is quite different than the ls command, though we get much of the same information as before – the owner is user1, the group is user1, and the Unix permissions are 770, or rwxrwx – – – .

Extended ACLs offers a much greater range of permissions than what we see here, however.  Using the setfacl command, we can add multiple users or groups, and even set inheritance on the file.  Using setfacl with the -m parameter specifies that we want to modify an ACL on a directory, while -x specifies that we want to remove an ACL entry from a directory.  Additionally,  the u: or g: notation is used to determine whether the ACL entry applies to the owner (u:) or group (g:).  Furthermore, the -d parameter gives us the ability to set a default ACL on the directory, so that new files and subdirectories will inherit the parent ACL.

Let’s start by taking a look at an example where we want to set defaults on a parent directory:

Now let’s take a look at what these commands are doing.  In the first two lines, we’re setting the permissions for the default user and group.  In the last three lines, we’re setting a default ACL for not one, but three separate groups’ permissions on this directory.  The first two groups, group1 and group2, both have read, write and execute, while group3 has read and execute only.  Taking a look at getfacl again on this directory, we can start to see the permissions taking shape:

Next, let’s grant explicit ACLs on the parent folder.  These commands look similar to the default ACLs, less the -d parameter.

Now we have a full set of permissions on this folder.  We’ve set defaults for the owner and the group, as well as defaults for three specific groups.  We then added permissions for the owner, group and three groups to the folder explicitly, giving us much greater granularity than with traditional Unix permissions alone.

There’s one more item we might want to consider, however.  Note what happens when we create a new sub-directory within the files directory while logged in as user1.

We see that since the folder was created as user1, whose primary group is also called user1, the group for this new directory also becomes user1.  Though not technically part of the extended acl set, we can use an additional chmod command to offset this behavior, called the setgid flag.  Now, it’s important to note that the setgid flag means two very different things when applied to directories versus files.  When applied to a file, the setgid flag allows users to execute a file as if they were a member of the file’s group; the command actually means, “set group id upon execution.”  In our case, this isn’t the behavior we desire.  When applied to a directory, however, setgid takes on a different meaning.  In the context of a directory, setgid forces new files and folders created within the parent to take on the parent’s group, regardless of the group to which the user that created the file or folder belongs.

Let’s now set the setgid flag on the parent folder as follows:

Looking at the permissions we see a new attribute, called flags, with the set id flag in the group position.  Finally, let’s recreate the new sub-directory as user1.

Note that now, although the new directory was created by user1, the group attribute has retained the value of the parent, group1.  It’s also important to note that our new sub-folder has inherited the defaults of the parent folder as well as the specific user and group permissions from the parent.

File Masks

One final note regarding the mask attribute before we conclude.  Simply put, the mask implies the maximum permissions that may be applied to a file or directory. In all of our examples you’ll note that the mask is set to rwx, so rwx is the maximum permission allowed.  Were we to implement a mask of r – – , however, read-only permissions would be the maximum permissions allowed, regardless of the explicit permissions for a named user or group.  Put another way, if a mask is r – – but a user has rwx, the effective permission is the overlap between the mask and the explicit permission.  In this case, the permission becomes r – – since the read permission is the only position that overlaps between the two.

This becomes a bit clearer when we see it in action.  Let’s take the parent folder from before, but assign a default and explicit mask of r – – .

Notice now that when we view the permissions on this folder, we see that although group1 and group2 explicitly have rwx permissions, they only overlap the mask on the read-only value, thus read-only becomes the effective permission.  From this we can see why it’s important to keep an eye on the mask attribute, as it can “mask” the permissions we intend to set for a user or group.  As a rule of thumb when using extended ACLs, it’s sometimes more straightforward to simply leave the mask as rwx, control access by thoroughly applying group permissions, and ensuring no other users have access to the files.  This prevents any unexpected behavior for explicitly defined user or group ACLs.


While this is by no means an exhaustive review of Linux ACLs or even traditional Unix permissions, this article has hopefully given you a good overview of the additional flexibility that ACLs bring to the Linux file system.  Coupled with traditional Unix permissions, extended ACLs give you near Windows-like file and folder manageability.  This becomes even more evident when using Linux to serve files or FTP, especially in a Windows environment.