Chapter    4

File System Permissions

File system permissions are your data’s first line of defense in a multiuser environment. A well-managed permission scheme ensures that your data is accessible and modifiable only by the proper people. The file system, after all, is the gateway to your data. An ineffective permission scheme is the equivalent of handing your data out to anyone who would express interest in it, or even worse, allowing them to destroy it. Furthermore, poorly implemented permissions can serve a different evil, preventing honest, hardworking Joe from accessing either his own documents or documents created by his collaborators.

Thus, file system permissions cover the triad of information security: confidentiality (ensuring that your sensitive data isn’t viewed by the wrong eyes), integrity (ensuring that data isn’t manipulated by unwanted parties), and accessibility (ensuring that the right parties can access data consistently and reliably). This is no light matter: a small change to permissions on a directory toward the top of your file system hierarchy can have wide-sweeping effects in all three areas. Suddenly, that chmod –R 777 command that you read about online and are about to run might not seem like a good idea, and it probably isn’t (if you don’t understand what this means, don’t worry, you will by the end of this chapter). Too many environments take a lax view on file system permissions simply because it’s easier not to have to deal with them. Unfortunately, many people don’t realize the importance of data security until they have to reassemble the damage caused by poorly managed permissions on vulnerable data.

This chapter covers the ins and outs of file system discretionary access controls provided by OS X version 10.11. Specifically, we will explore techniques utilizing all of El Capitan’s tools (graphical and command line) to help ensure that your data is accessible by those who need to access it and safe from manipulation by those who don’t.

In this chapter we will also examine the impact of file system permissions on the security of an operating system itself. Permissions problems can lead not only to exposed or vulnerable data, but also to the complete compromise of your system.

Mac File Permissions: A Brief History of Time

For many Mac users, the concept of file system permissions is both relatively new and oft misunderstood. First introduced in OS X, file system permissions were a drastic departure from Mac OS 9’s largely unprotected system, a trait reflecting the earlier system’s single-user nature.

With OS X came a true multiuser OS, born of Unix roots and as such, a POSIX-compliant (Portable Operating System Interface) file system permissions implementation. If you’re scratching your head right now, don’t worry; the term POSIX simply refers to a series of standards covering a number of OS conventions, of which the most relevant to this chapter are those covering file system permissions. Outside of Windows, the POSIX permissions standard has been the primary permissions model used by every relevant operating system on the market today. Realistically, this boils down to all of the various Unix and Linux distributions out there. Windows does itself provide a POSIX-compliant file system in NTFS, though its primary permissions model is based on Access Control Lists (ACLs), which we will get to in a bit.

The basic premise found in a POSIX-compliant permissions scheme is that each file system object, say a file or directory, has associated controls that determine the level of access a user is granted to that object. In such a scheme there are three access levels (referred to as modes) that can be defined for an object: read, write, and execute. These three levels can be applied for each file or folder at three distinct targets: the file’s owner, the file’s group, and everyone else. With POSIX, a file system object can have only one owner or group; so at first glance, this may seem somewhat limiting, and it certainly can be. However, you can actually establish quite complex and workable permission schemes using POSIX alone.

ACLs were introduced to OS X in version 10.4 and provided a new approach to permission access to files. While the POSIX standard does have a working draft for ACL permissions in the form of the POSIX1.e proposed standard, the status of the standard is very much in limbo, to say the least. Apple instead chose to implement an ACL system based on the NFSv4 standard as defined in RFC 3010. This standard is implemented in a way that makes it compatible with ACL implementations utilized by Windows systems beginning with Windows NT. Other systems that include support for NFSv4 ACLs include Solaris and FreeBSD9. Most Linux systems adopt the POSIX1e ACLs, which support only a subset of access controls provided by the NFSv4 system.

With The OS X ACL implementation, each file system object contains a single access control list table, which contains multiple access control entries (ACEs). Each ACE defines a subject and a set of specific access rights. In OS X, the subject can be a user or a group, and there are up to 17 different access rights that can be explicitly allowed or denied for any file system object (access control rights are discussed in detail later in this chapter). On top of this, a particular file’s access control list is completely extensible, which means that an arbitrary number of ACEs can be assigned to any particular file system object. Basically what this means is that ACL-based file system permissions allow for extremely granular and flexible management.

In early OS X incarnations, permissions problems were common among long-time Mac users, and to a degree they still are. However, any permissions problems that persist in a 10.11 environment are, plain and simple, due to poor administration (which isn’t to say that we don’t hear a lot of people still blaming all of their problems on there being something wrong with ACLs or their being too complicated). The truth is that in the earlier days of OS X, permissions problems were abundant, and they were due not only to user inexperience but also to significant limits of OS X’s permissions implementation. Although OS X has always had a basic POSIX permission system, in the early days there were fairly significant limitations to its implementations that made it difficult to properly harness. Luckily, the OS X permission system has continuously improved throughout the life of OS X, and since 10.6 we have had a combination of basic POSIX permissions and ACLs that provides for rock-solid, flexible file system permission structures.

POSIX Permissions

As previously mentioned, basic POSIX permissions have been with OS X since its inception. Using POSIX, you can apply access restrictions to three different classes: that of the owner, of the group, and of everyone else. A file references its owner or group based on an ID that is stored directly with the file. In order to determine the actual owner or group of a file, the OS cross-references the file’s user and group IDs against its Directory Services database.

For instance, every OS X system out of the box has a local user admin, created with user ID 501, and the default group staff, which has an ID of 20. Therefore, any file that is owned by the user ID 501 and the group ID 20 is owned by the user admin and the group staff, respectively. The third class is implicit for anyone that is not user admin or a member of group staff. When qualifying for access to a file or directory, OS X will first check to see if the requested file or directory is owned by the effective owner or group of the currently running process. If the system determines that the user is the owner, the user will receive effective permissions assigned to the owner class. All other classes will be ignored. If the user is a member of the group associated with the file or directory, and is not the owner, then the user will receive effective permissions assigned to the group class. If the user is neither the owner nor a member of the file/folder’s group, then the user will receive effective permissions of the “everyone” class.

Note  If the user is the owner of the file, and the file’s class does not have write permission, then the user will not have write privileges to the file regardless of “group” or “everyone” class permissions.

Modes in Detail

Each class has three possible access capabilities, represented by three modes:

  • Read: The read mode, when set on a file, allows a user to read its contents. For a directory, the read mode grants the ability to list its contents.
  • Write: The write mode allows a user to modify a file’s contents. When set on a directory, the write mode grants the ability to create subfolders or files. It also allows the user to rename or delete files it directly contains, even if the user does not have write privileges on the file she is attempting to rename or delete. If a user does not have write privileges to a directory, she will be unable to rename, move, or delete any items directly residing in it, even if she has write privileges to the item itself.
  • Execute: The execute mode grants the ability for a file to execute in the system. This is not the same as opening a file. Execution implies that the file contains either compiled executable binary data or scripting text, which references an interpreter via a hash-bang (#!) statement, such as a shell script. For instance, if we were to write a basic bash shell script named “Click Here For Cool Stuff,” save the file, and then grant ourselves execution privileges to that file, we could simply double-click it for it to execute. If this script were malicious in intent, for example if it provided instructions to delete all data that the user can access, then that malice is only a double-click away for any user that has access to the file, and it has a fairly intriguing name that many of your users would likely freely click. (Who doesn’t want to see cool stuff?) If that malcontent script does not have execution privileges assigned, then it’s largely relegated to a text or binary data file. Once execution is granted, it becomes a significant and warranted threat to your user base. This is not to say that the data is completely harmless without execution rights, but removing the executable bit means that the code will not be a double-click away from execution.

When applied to a directory, the execute mode grants the ability to traverse a directory. Essentially, this mode controls the ability to access any resources that exist in this directory. When applied to a directory, the execute mode is nondiscriminating and absolute; without execute permission on a directory, you will not be able to access any items inside that directory regardless of permissions or the depth of any of its containing items.

Note  When set on a directory, the write mode grants the ability to rename its direct descendants, even if the user does not have write privileges on the subfolder or file they are attempting to rename. This has significant security ramifications: any directory that contains directly executable code or referenced code that will operate under the root user, or otherwise in system automations or routine maintenance, should be closely scrutinized. It is a possible vector for attack; a malicious user can rename the executable or referenced code and inject his own routines, thereby compromising your system in full or part.

As an exercise, if we were to remove the execute permissions from the root directory of our volume, /, then a significant number of critical processes, including our own user environment, would fail to operate properly due to lack of resources. By eliminating execute privileges on the root directory, we essentially cut off access to all data on the drive. Denying execute privileges is a good way to completely block users from accessing data at the perimeter of a directory structure, thus allowing you to continue to use owner, group, and everyone management on subdirectories with impunity from users that don’t meet criteria further up the tree.

Contrast this to the read mode: if we were to simply remove read permissions from root, the ramifications would be far less drastic. We would not be able to view the contents directly of the root directory, but once we traversed into a subfolder, such as /Applications (possible because it is executable), we would be subject to the permissions of the Application’s folders, and subsequently the permissions on any of the individual files in that subdirectory. Now, because we don’t have read access to list the contents of the root volume, we wouldn’t be able to traverse into a subfolder unless we knew that it existed and what it was named. But this type of security through obscurity can also be bypassed. What we want to emphasize here is that denying users read privileges on a directory will not prevent them from traversing into its subdirectories, where they’ll have any access granted at the applicable owner, group, or everyone classes, a potentially less secure environment.

Modes are established on a file through the use of a bit-flag system. To truly understand this system, look at it from the command line (we will cover GUI permissions shortly).

For example, consider the list of files and directories in the /Users folder that the command ls –al /Users produces, shown in Figure 4-1.

9781484217115_Fig04-01.jpg

Figure 4-1. Output of command ls –al /Users with permissions, owner, group, and folder name identified

As illustrated in the figure, in every line of the output, the first field (the one containing combinations of dashes and the letters d, r, t, w, and x) reports the POSIX permissions. For clarity, let’s look at the emeraldedge folder:

drwxr-xr-x+ 20 emeraldedge   staff  1870 Jul 8 00:56 emeraldedge

Here, the string drwxr-xr-x defines the POSIX permissions. In an ls -al output, the first digit, d, specifies the file system type, and in this case, a directory. Other common entries include a dash (–) for a file and l for a symbolic link. The next three characters, rwx (read, write, and execute), represent the mode for the owner, who in this example is emeraldedge. Thus, user emeraldedge has read, write, and execute privileges for this folder. The next three digits represent group privileges: Staff has read and execute privileges. The final three characters represent permissions for everyone else: in this case, only read and execute privileges.

On a lower level, POSIX uses bit flags to represent modes. This means that permissions are represented by a unique numerical value. The read, write, and execute modes are each represented by three bits. The easiest way to illustrate this is by comparing it to our previous ls output.

drwxr-xr-x
d111101101

As explained earlier, the first three characters after the d designate permissions for the owner. In this case, rwx is represented in binary as 111, which has a decimal value of 7. The group also has rwx privileges, which is also a decimal value of 7. The everyone class has only read and execute permissions, r-x, which is 101 in binary and a decimal value of 5. Thus, these permissions translate to 775 in their decimal form, a common type of notation called octal notation. See Table 4-1 for a better representation of the permissions layout.

Table 4-1. Permissions Represented in Alpha, Binary, and Octal Format

Table4-1

You don’t really need to be able to do binary math in your head to manage POSIX permissions, but knowing the numeric values of each mode can be important, as they are commonly used when managing permissions from the command-line interface, as discussed later in this chapter.

Inheritance

Another aspect to understanding POSIX permissions in OS X is inheritance, or how the system deals with group assignment on newly created files and directories. Apple is compliant with Single Unix Standard, version 3 (SUS3), which dictates that the group established for the new file will be inherited based on group ownership of the parent directory. This system allows you to use group permissions on directories to establish group-specific collaboration areas. For instance, imagine that user jdoe creates a file in the Workgroup1 folder, which has the group workgroup1 assigned to it. The file will be owned by user jdoe and will have a group of workgroup1 regardless of the primary group assigned to jdoe’s user account. The user can then browse into the Workgroup2 folder, and create a file under that folder. The second file will have a primary group of workgroup2.

There are a few potential wrinkles in this plan. First, if it’s not planned properly, the new behavior of group inheritance on files and folders may have some unexpected side effects. For instance, if you are using file system quotas, it is important to note that when establishing group ownership on a directory to a group that has quota limitations, any new files in that folder will count against the group quota. Thus, if you are using quotas, you need to take this consideration into account when structuring your hierarchy. The second problem is that, by default, OS X ships with a umask value of 022. The umask is a value that is used to determine default permissions on newly created files. When a user creates a file, its established permissions are determined by taking the default mode of 666 (777 for new folders), and then filtering that value by the user’s umask value (022). To determine ultimate privileges, you simply subtract the number representing the umask from that of the privileges. So in this case, newly created file system objects will have a mode of 644 (666 minus 022), or rw-r--r--.). It would be an extremely bad idea for all new files to be executable, so their default mode is 666. On the other hand, if folders don’t have execute permissions, then no one will be able to navigate into them. Thus, folders have a default mode of 777. The umask is then used to determine final permissions for any new files or folders.

The main problem with a file that has rw-r--r-- (644) permissions is that the middle octal, the group octal (r--), assigns read (r) permissions, but no write (w) capabilities. This is a very important thing to understand: by default in OS X, newly created files are not group-writable. This means that when a user creates a new file in OS X, by default, only the creating user has the ability to modify (write) that file. Although this is the most secure configuration, it immediately becomes a problem when more than one person needs to modify that file. Failing to recognize this leads to serious permissions problems when using POSIX permissions in a collaborative environment. Luckily, you can change the user’s umask. To do this, we must first calculate our desired umask. In most cases, we want new files to be writable by both the creating user and the group owner of the file, which is represented as rw-rw-r-x visually or as 664 using octet representation. To determine the umask that we want to use, we subtract our desired mode for new files (664) from the default file mode (666). 666-664 is 002, thus our desired umask is 002.

To apply this umask in OS X 10.5 or later, simply run the umask command with the desired mode /usr/bin/umask 002.

Unfortunately, executing umask may not affect all running processes, and the result won’t persist across reboots. To remedy the situation, we recommend using the launchd-user.conf file found at /private/etc/launchd-user.conf. To set this, simply run

echo "umask 002" >> /private/etc/launchd-user.conf

as root. That’s it. Reboot and you’re done. From now on, whenever your machine boots up, it will read this file and set the desired umask value for any user sessions.launchd.conf at the root of their home directory.

If you’re running OS X 10.4 or earlier (not likely, but it could happen), the process for changing the umask is slightly different and a lot more complex. We recommend installing the program Umask Doctor and setting it to launch at login if you do not wish to do this programmatically. This utility specifically performs this duty, and it works out pretty well. Alternatively, you can simply make the change via the defaults command, run with root/sudo privileges:

defaults write /Library/Preferences/.GlobalPreferences NSUmask 2

Note, however, that the NSUmask value is actually a decimal value of the octal umask, so you’ll have to do a conversion. In other words, instead of viewing the number 777 as three different values of 7 (owner), 7 (group), and 7 (other), it instead views it as a single number: 777.

The approach to determining the decimal umask for this command is to convert the binary representation of the umask octal to decimal, so a little knowledge of binary is required.

For example, let’s examine a umask of 022. If we convert each of these octets (0,2,2) into binary, the values are 000 (0), 010 (2), and 010 (2) (when doing this conversion, it’s important to always use three significant digits). After converting each octet into binary, the next step is to concatenate the values. In this case, 000, 010, and 010 become 000010010. This value, when converted to decimal is 18 (0 × 20 + 1 × 21 + 0 × 22 +0 × 23 + 1 × 24 = 18). This decimal value is then the number to substitute for the NSUmask value. One other note: the programs that honor the NSUmask will typically operate in an OS X GUI environment, as it is a function of the Cocoa framework. Technically, command-line applications can support this property, but typically command-line apps will utilize the more traditional POSIX/umask model. Not all third-party Cocoa programs support this value, but generally the major players do.

Once you have set the umask, simply restart the computer. From then on, that computer will freely interact in collaborative folders, and other group members will be able to modify files that its users create without having to file a help desk ticket. Neat.

Note  Fortunately, if you don’t know binary, the OS X Calculator app has a programmer mode that does all the mental work for you. To access this function, open up the Calculator application, found in /Applications, and then select Programmer in the View menu (or use the keyboard shortcut image+3).

The Sticky Bit

For day-to-day management of POSIX permissions, the three modes we previously discussed (read, write, and execute) will be your primary weapons against those pesky permissions issues. But you do have a few more tools at your disposal. In a previous ls output we showed, you may have noticed some special permissions on the directory /Users/Shared. Here’s the line again:

drwxrwxrwt 13 root   wheel  442 Jun 29 23:54 Shared

Under the “everyone” digits (the letters in bold), instead of the expected x (execute), we have a t. This is referred to as the sticky bit. This bit has no effect on files in OS X, but when enabled on a directory, it prevents deletion or renaming of files inside of that directory by anyone other than the file’s owner. Thus, if Jimbob creates a file and then gives everyone read and write privileges (or if you modified the umask), Geraldine will be able to edit its content, but not delete it or rename the file. Only Jimbob can delete the file. It’s worth noting, though, that with write privileges, nothing stops Gerry from simply deleting all of the file’s contents. The sticky bit simply disables the user from completely deleting it.

To assign the sticky bit to a directory, you simply use a fourth octal number, which has a value of 001. Thus, the Shared folder in the previous example line has a mode of 1777, with the 1 (001 binary) being the “sticky” directory. To apply this mode to a file, use the chmod command. Run it as root if you’re the owner of the targeted directory:

chmod 1777 /Users/Shared
chmod –R 777 /Users/Shared/*

The second line specifies the –R flag, which will apply the mode 777 to all items in the /Users/Shared/ directory. Thus, all files in the directory will be editable by anyone, but because of the first command that was run, only the owner can delete a file.

The suid/sguid Bits

The fourth octet has two modes in addition to sticky: set-group-ID-on-execution, which has a value of 010, and set-user-ID-on-execution bit, which has a value of 100. If either of these modes is set on an executable, whenever that file runs, it will do so in the context of the owner and group assigned to it. Thus, if a program is owned by root and has setuid on, whoever runs that program will have root access (within the confines of that program). This is a bit of a scary thought, so use this capability with great care. Many a local privileged-escalation exploit has been born from the setuid bit. In the early days of OS X, it was possible to set the suid bit on shell scripts as well as other interpreted scripting languages (Python, Perl, Ruby, and the like). Shell scripts have numerous attack vectors, and Apple considered this to be a large security risk. Thus this is no longer applicable. The suid and guid bits will now only be honored on precompiled binary executable files. Additionally, regardless of what the man page for chmod claims, the suid and sguid bits have no effect on directories in OS X. They are simply ignored. In general, use of the suid bits should be extremely limited and rare. OS X is one of the worst offenders of this principle, as OS X has historically had a large number of suid programs in a default number. Thankfully, the number of programs that ship with this privilege is reduced with each iteration of OS X. It is important to note that the setuid and setgid bits are not honored on removable file systems. This is important, as it provides protection against a rogue program that is introduced from a foreign (and potentially contaminated) file system, such as a Thunderbolt, Firewire, USB, or optical drive. This prevents a malicious user from being able to introduce setuid and setgid programs into the environment.

Note  You may want to occasionally audit which executables in your system have the setuid and setgid bits set, as any executables with such privileges are potential attack vectors by local users. To see a list of all such files on your system, you can use this command:

   find / -type f ( -perm -4000  -o -perm -2000 ) -ls

POSIX in Practice

So that is POSIX permissions in a nutshell. The system may seem somewhat limited; but really, you’re limited only by your own ingenuity and the speed at which your fingers type. In a POSIX environment, groups and nested hierarchies are your friend in creating collaborative environments, though it is also important to pay attention to file-level permissions as well to ensure data confidentiality and integrity. To illustrate this, we’ll walk through some complex permissions scenarios and discuss strategies for deploying POSIX permissions.

One environment where complex POSIX hierarchies are crucial is education. Consider the various levels of accessibility that servers in an educational institution would need configured. Education environments have needs for private file-sharing collaboration areas among faculty. Such a file share needs to have facilities to provide documents to students, facilities for students to collaborate (share files with each other), and finally it is necessary for students to provide teachers privately with documents that cannot be viewed by other students (hand-in assignments).

To fulfill these various needs, you must first examine how you want to structure your data. Do you need to isolate faculty data from student data? Should it be on a different server altogether, or is it OK to store on the same volume as the rest of the student data? What kind of faculty data should be stored on a server with student data? Will faculty be storing only class-relevant data on this data store, therefore making it okay to group faculty data along with student data? This illustrates a very important point: securing your permissions on your file system is only part of your solution. It is important that you, as the admin, educate your end users on acceptable use policy, data security policies, and practices. For instance, it would be a very bad idea for your teachers to place personal information about students, such as social security numbers, medical information, and so on, in a public location. This may seem like simple common sense, but as an administrator it is your duty to ensure that your users are educated and in line with company/organization security best practices and policies.

So, with all considerations in mind, we have devised an appropriate permissions hierarchy to allow students and teachers to utilize their file storage securely. There is a top-level folder MySchoolShare that contains course-specific subdirectories: Comm101, English101, and Sci101. Each of these contains a folder template that is meant to securely address our access requirements. Let’s take a look at an ls –al output for the folder Comm101:

drwxr-x---      7       root      comm101         238 Jan 24 14:37 .
drwxr-xr-x      6       root      staff           204 Jan 24 14:44 ..
drwxrwxr-x      2       root      comm101staff    68  Jan 24 14:20 Course Files
drwxrwx-wx      2       root      comm101staff    68  Jan 24 14:20 Hand-ins
drwxrwx---      2       root      comm101         68  Jan 24 14:20 Public
drwxrwx---      2       root      comm101staff    68  Jan 24 14:19 Staff

In this template, to even be able to access the directory, the user must be a member of thecomm101 group (as is seen on the “.” entry). In this case, the comm101 group would contain members from both the comm101staff group and the comm101students group; thus we have a group that qualifies either set of users. The Comm101 folder itself allows only for read and execute permissions to the comm101 group, which means that users will not be able to add any top-level subdirectories or files and prevents them from renaming any existing items. This allows the administrator to define a folder template structure and ensure that users, whether faculty or students, adhere to it.

The Course Files folder is used by instructors to provide course-specific files and templates to students, and so write privileges are limited to the comm101staff group. All users have the ability to read files from this directory, as they qualify for the “everyone” class. In this case, the “everyone” class is guaranteed to contain only members of the comm101 group that are not also in the group comm101staff. We know this because of the permissions on the Comm101 folder itself:

drwxr-x---      7       root    comm101         238 Jan 24 14:37 .

These permissions indicate that any items inside of this folder are accessible only by members of group comm101. Therefore, the “everyone” class on any subfolders or files is effectively restricted to the comm101 group, or a subset of it.

The Hand-Ins folder is used by students as a drop-box: a folder where they can add their own files but cannot read any files it contains. This allows a place for users to provide teachers with their homework assignments and not have to worry about other students viewing those files. Because the Hand-Ins folder provides all members of the group Comm101staff with read, write, and execute privileges, any members of that group can access and view files provided by students for review. A drop box is created by allowing users write and execute permissions on a directory, and is indicated by the special drop-box icon, shown in Figure 4-2.

9781484217115_Fig04-02.jpg

Figure 4-2. A Finder drop-box folder

The Public folder in the example hierarchy provides a place for all users of the comm101 group to collaborate. This means that both students and faculty will have the ability to modify, add, or remove files from the directory. It’s a bit of the wild, wild west permission-wise, but it allows a place for everyone to collaborate, which is often desirable in a classroom setting. We make the folder public by ensuring that it is owned by the more global comm101 group, and that all members of the group have read and write capabilities, as shown in the trimmed ls output:

drwxrwx---      2       root      comm101          68  Jan 24 14:20 Public

In this case, we may want to set the sticky bit on this folder to ensure that users can delete only their own files from this folder. Last but not least, we have the Staff folder, which is a folder where teachers/instructors can privately share files outside the purview of students. This can be handy for substitutes, multi-instructor classes, or for professors who have to collaborate during the teaching process. To facilitate this, the comm101staff group is set as the primary group and given full read and write access. Students, who will receive effective permissions of the “everyone” class, will then have no access to any items in this directory, as made evident by the permissions on the folder:

drwxrwx---      2       root      comm101staff   68 Jan 24 14:19 Staff

Caution  A good permissions hierarchy is only a partial solution. As an administrator, it is important that you take precautions to protect your data on a social level by educating your users. If they are not aware of the consequences of placing a sensitive file in a potentially public area (such as a folder named “Public”), you will likely have a security breach due simply to user ignorance.

Access Control Lists

Mac OS X 10.4 saw the introduction of ACLs, and Apple has continually refined them through the various iterations of OS X since then, providing a mature and robust access control system in 10.11. For a traditional Windows system administrator, ACLs are likely easier to work with than POSIX. ACLs match the permission options almost identically. In fact, as we mentioned earlier, the OS X NFSv4 ACL format is compatible with Windows ACLs.

A file’s access control list is completely extensible, allowing you to assign very granular permissions to specific users and groups. It frees you from the constraints of the POSIX user/group/everyone paradigm, which greatly simplifies permissions management. On top of their extensibility, ACLs also define numerous access levels and inheritance capabilities, which allows for especially effective permission hierarchies.

Access Control Entries

There are 17 access rights that the ACL system allows you to apply to a file or directory. An access control entry, or ACE, is simply a specification that includes either a user or a group combined with an allow or deny directive, and a comma-separated list of one or more rights. These rights can be grouped into four categories: Administration, Read Permissions, Write Permissions, and Inheritance.

Administration

The Administration category includes two permissions capabilities:

  • Change Permissions: Users with this right can manage privileges on a file via POSIX or ACLs. They may also delete any ACLs on the file or folder, so assign this permission with caution. When using chmod to manage ACLs (as discussed later), you grant the change permissions with the writesecurity privilege.
  • Change Ownership: Enabling this for a user allows that individual user to assume ownership of a file. However, that person can’t transfer ownership to anyone else. To do so, a user must have root access. You can grant the Assume Ownership privilege with the chown permission when using the chmod utility, which we’ll discuss a bit later in this section.

Read Permissions

The Read category includes five specific permissions:

  • Read: The read privilege behaves similarly on both files and directories, letting users view the content of both. If you’re working with ACLs from the command line, you grant this right using read for files and list for directories.
  • Execute/Search: The execute and search bits behave similarly to the execute bit in the POSIX model, though they are now given differentiating descriptions to more clearly define the delineation between the execution capability that the attribute provides when applied to a file and the list/traverse behavior when it is applied to a folder. From the command line, you grant this privilege using the execute permission for files and the search permission for folders, although the terms can be used interchangeably when applying to either.
  • Read Attribute: This permission is granted, using the readattr privilege, to let a user view the data describing a file’s characteristics, such as its size, ownership, mode, inode number, and file creation, modification, and access times. You enable this permission with the readattr privilege.
  • Read Ext Attribute: This permission allows a user to read a file’s extended-attribute data: file attributes commonly utilized by the OS, such as information about the OS X quarantine system, Time Machine, disk-image checksums, and third-party software for metadata purposes. Extended attributes are also responsible for the data found under the More Info tab when you get information on a file. Use the readextattr permission to grant this right.
  • Read Permissions: Given this privilege, a user can view security information, such as ACLs or POSIX permissions, as well as ownership of a file or folder. To assign this right, use the readsecurity privilege.

Write Permissions

The write-permissions category allows users to create and modify file data, including file metadata stored via extended attributes. There are six specific write permissions:

  • Write Attributes: This permission allows a user to change a file’s attribute data.
  • Write Ext Attributes: Granting this right lets a user edit files’ and folders’ extended attribute data (extra information about a file’s traits) as well as create new entries in that data. You’ll rarely want to make such data user accessible, though. Software behind the scenes usually manipulates this data.
  • Write/Add Files: The Write and Add File privileges are analogous when applied to a file or directory. Like search/execute, the two terms exist solely to illustrate the functional difference when applied to a directory versus a file. When applied to a directory, the add_file privilege serves as a subset of the POSIX directory write capability. The key difference is that, unlike the POSIX write capability, the add_file permission does not grant the ability to delete a file or create a new directory. These abilities are now bestowed by delete and append, respectively. When the privilege is applied to a file, the user will have the ability to modify the contents of the file. When applying ACLs via the command line, you can use write on both directories and files, but on directories, it’s ultimately interpreted as the add_file permission.
  • Delete: This capability is a subset of the POSIX write capability. With ACLs, we now have a specific right granting a user the ability to delete files or directories. This right is defined by the privilege delete.
  • Append/Add Directories: This capability is also a subset of the POSIX write capability. When applied to a directory, it allows users to create new subdirectories. When applied to an existing file, it allows the user to modify the file. Note that to create new files, a user must have write privileges. Using chmod from the command line, you assign the append/add directories privilege using append. The flag is interpreted as add_subdirectory.
  • Delete Child: This permission, which applies solely to directories, lets a user delete any file directly residing inside the directory, regardless of ownership on the item. In the case of subdirectories residing in this directory, the subdirectory can only be removed if the user also has the ability to delete any files it contains. The delete_child flag assigns the right.

Inheritance

This category applies solely to directories. You would use inheritance to customize how permissions are inherited by a directory’s children. For example, if you apply ACL inheritance to just the first level of subfolders and files, new folders that users create will inherit their parents’ permissions, but items created inside the new folders will not. Likewise, by using the inherit_only flag, you can assign ACLs specifically for inheritance, but not have them apply to the parent object, which can be very useful. You control inheritance with the four separate rights in the following list:

  • Apply to This Folder: When this is selected, the ACL will apply to this folder. Otherwise, the folder will have only_inherit permission, and the ACL will be active only on children that inherit the ACL.
  • Apply to Child Folders: When you activate this option, newly created child folders of the directory will inherit the ACL. Use the directory_inherit permission to grant this privilege.
  • Apply to Child Files: When enabled, this privilege will cause new files created in the directory to inherit the ACL. You use the file_inherit permission to grant this right.
  • Apply to All Descendants: If you activate this option, the inheritance properties of the directory will pass on to newly created directories; allowing for automated propagation of ACLs as users create additional directories and files. Otherwise, the directory you’re currently attending to will have the limit_inherit privilege.

The specificity of the various access rights allows you to more pointedly prescribe access. You can now differentiate between modification and deletion as well as differentiate various rights to files and folders. More importantly, ACLs provide multiple options to define inheritance, which can be very handy in establishing complex permissions hierarchies, such as those in education.

Caution  If no Access Control Entries are applicable for a particular user on a file, ensure that your baseline POSIX permissions are structured in a manner to prevent unauthorized access. In some instances, it may be desirable to utilize explicit deny ACLs to ensure that access is unconditionally restricted.

Effective Permissions

One major limitation of ACLs can be found in protocol support. In order to utilize ACLs, a protocol must be built to support it. Apple has mitigated this issue by building ACL support into its first-party file systems and network protocols: HFS+ (Hierarchical File System, the OS X native file system), Xsan (Apple’s cluster file system based on Quantum/ADIC’s StorNext file system), and AFP (Apple Filing Protocol, Apple’s native file sharing protocol). Thanks to its NFSv4 ACL implementation and the Samba open source project, OS X also includes support for ACLs via the CIFS protocol, which is used for connecting to and serving files to Windows clients.

So what about services that do not include support for ACLs? How do they handle permissions provided via ACLs? Luckily, on a standard OS X server this list is pretty short. The most notable offenders are FTP and NFS, but certainly that is not an exhaustive list. The fact that the OS X NFS daemon doesn’t support ACLs might have you raising an eyebrow. After all, the ACL model utilized by Apple is based on the NFSv4, right? Unfortunately, Apple’s NFS implementation supports only versions 2 and 3 of the standard, which don’t yet have ACL support. Even if this wasn’t an issue, there are definitely scenarios where you’ll be providing file services over a nonstandard protocol that most likely does not include native support for ACLs. In any of these scenarios, the protocol in question will operate under what is referred to as “effective permissions.” Essentially, permissions as defined by the ACLs will be flattened into equivalent POSIX permissions. This means that if you have an ACL that prevents append access to user jdoe on folder folder1, then when user jdoe connects to folder1 over FTP (which does not support ACLs) and attempts to create a new subfolder, the action will fail. The same is true of NFS shares; exported NFS shares will boil down to effective permissions. The NFS implementation in OS X doesn’t support ACLs, but it does honor them via effective permissions: if a user is granted read/write via an ACL, they will have read/write access via NFS. However, there are a few things to note here. First and foremost, granular ACLs won’t translate completely. Second, although you might have effective write privileges via ACLs, if you don’t have write privileges via POSIX, it will seem as if you don’t have privileges when you run ls on the mounted NFS volume; however, if you try to read or write a file, it will work without issue. Poorly written third-party software might inspect the POSIX permissions and determine that you don’t have access to an asset when you really do. However, most software will attempt to read/write an asset and will only report errors when encountered (as it should).

Also, for cases such as this, ACL inheritance is honored. For instance, an ACE on a folder ensuring that all created subfiles have write permissions will in fact appropriately apply the inherited entry to files uploaded via FTP or created via an NFS mount. You won’t be able to view the ACL strictly across the FTP connection or the NFS mount; but on the back end, if you check the file on the server, you will see that inheritance is in fact applied to new files.

Note  If you are using a third-party file service that runs as root and implements its own abstracted permission system, effective ACL permissions will not apply.

ACLs in Practice

We have now covered all of the various rights provided by the ACL system, but how can we use the system in practice? Well, the granular and specific nature of ACLs makes the system a little less difficult to wrap your head around than a POSIX permissions structure. With basic POSIX permissions, you have to be somewhat clever with your folder hierarchies and group structures to create a workable system. With ACLs, the approach is much more clear and direct. Let’s consider the example that we discussed earlier in this chapter, in the section “POSIX in Practice,” in which we discussed a permissions hierarchy for a school that seeks to provide collaborative file sharing environments for its Comm101, Science101, and English101 classes. Although we were able to accommodate the schools requirements solely with POSIX permissions, what if there were more requirements attached to that problem? For instance, let’s say there is a Comm101 teacher’s aide who needs access to the Staff folder for collaboration, but is not permitted access to student’s final work delivered to the Hand-Ins folder. Likewise, this teacher’s aide needs to be able to add files and directories to the Course Files folder, as well as modify existing assets in that folder. To accomplish this task in POSIX, it would be necessary to create an additional group in our Directory Service, such that we could assign privileges as follows:

drwxr-x---      7       root    comm101                 238 Jan 24 14:37 .
drwxr-xr-x      6       root    staff                   204 Jan 24 14:44 ..
drwxrwxr-x      2       root    comm101contributers     68  Jan 24 14:20 Course Files
drwxrwx-wx      2       root    comm101staff            68  Jan 24 14:20 Hand-ins
drwxrwx---      2       root    comm101                 68  Jan 24 14:20 Public
drwxrwx---      2       root    comm101contributors     68  Jan 24 14:19 Staff

To accommodate the request, we have created a special group named comm101contributors, which now has access to the Course Files as well as the Staff folders. In order to access via the comm101staff group, that group has been added to the comm101contributors group, along with the teacher’s aide user.

This solution will surely meet the need, but it’s not long before you reach the practical limit of POSIX: what if the teacher’s aide is to be provisioned read-only access to the Staff folder? In order to accommodate that request and ensure that other students do not have access, you will need to create a subfolder that differentiates between comm101staff and comm101contributors. This is highly impractical. Instead, let’s revert to our original POSIX structure before creating the comm101contributors group, and approach the situation with ACLs in mind. The first thing to do is analyze the situation and determine whether the need to provide additional use is an edge case, or if it will become a common use-case scenario. If this will prove to be a common case, then we should create a comm101contributors group to manage access. Access would then be provisioned in Directory Services, thereby minimizing the need to change permissions on the file system.

Tip  In general, it is best to avoid provisioning ACEs to specific users. The larger your file structure and the larger your user base, the more management overhead will be needed as you provision specific user access. Moreover, the more often changes are made to a file system’s permissions structure, the more likely that human error will result in unwarranted exposure of data. Instead, it is best to define specific groups for any common access patterns that you expect to be needed by members of your organization.

In this case, we have determined that this is a very specific edge case, and so we will go ahead and provision our access to our teacher’s aide, who has a user account of comm101aid. To provide the necessary access rights, we will assign ACLs as demonstrated by the command ls –ael, which is run against our Comm101 folder.

drwxrwxr-x      7       root    comm101staff    238 Jan 24 14:37 .
drwxr-xr-x      6       root    staff           204 Jan 24 14:44 ..
-rw-rw-r--@     1       root    comm101staff    6148 Jan 24 15:05 .DS_Store
drwxrwxr-x+     2       root    comm101staff    68 Jan 24 14:20 Course Files
 0: user:comm101aid allow list,add_file,search,add_subdirectory,delete_child,readattr, image
writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit
drwxrwx-wx      2       root    comm101staff    68 Jan 24 14:20 Hand-ins
drwxrwxr-x      2       root    comm101staff    68 Jan 24 14:20 Public
drwxrwx---+     2       root    comm101staff    68 Jan 24 14:19 Staff
 0: user:comm101aid allow list,add_file,search,add_subdirectory,delete_child,readattr,image
  writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit

There are a few things to note about this ls –ael output. First, if we examine the POSIX permissions of a particular folder’s output, we will see that on some folders, there is a trailing + at the end. For instance, the Staff folder looks like this:

drwxrwx---+     2 root   comm101staff   68 Jan 24 14:19 Staff
 0: user:testaid allow list,add_file,search,add_subdirectory,delete_child,readattr, image writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit

The + character means that the file has one or more access control entries. When passed the –e flag, ls also outputs each files’ ACL, as seen on the Course Files and Staff folders. In each case, the user testaid has been allowed access permissions, which effectively provide Read and Write permissions in POSIX terms. The user testaid can read existing files and their metadata (list, readattr, readextattr), can traverse into the directory (search), add new files and directories (add_file, add_subdirectory), modify and rename existing files or directories (delete_child), and can modify file attributes and extended attributes (writeattr, writeextattr). On top of this, these permissions will be inherited by any newly created files or subdirectories (file_inherit, directory_inherit). This common combination of Read and Write privileges is utilized by a number of Apple’s administration toolsets. For a detailed table of Apple’s primary access groups Read and Write, Read Only, and Write Only (Drop Box), see the next section, “Administering Permissions.”

Through the use of ACLs we can easily adapt to various permissions needs. For instance, if the aide was only to have read permissions on the staff folder, we could apply the following ACL:

drwxrwx---+     2 root   comm101staff  68 Jan 24 14:19 Staff
 0: user:comm101aid allow list,search,readattr,readextattr,image
file_inherit,directory_inherit

This ACE would allow the user testaid read only access to the Staff folder, and any newly created items. Keep in mind that our POSIX permissions are still playing a role in this scenario, as the “everyone” group has no capabilities. This goes to illustrate the need to ensure properly planned POSIX permissions in addition to ACLs. It is not enough to rely on only one system. If necessary, we could apply an explicit deny ACL, which would override any set POSIX permissions:

drwxrwxrwx+     2 root   comm101staff   68 Jan 24 14:19 Staff
 0: user:comm101aid deny add_file,add_subdirectory
 1: user:comm101aid allow list,search,readattr,readextattr,image
file_inherit,directory_inherit

In this model, even though the user has the ability to create files or directories via POSIX permissions, they will be unable to do so, because of the explicit deny applied to the directory. Another important characteristic to note is how the ACL system resolves conflicting ACEs. In the event of two conflicting access privileges, the first entry found in the system will be applied. So in the previous example, if our allow rule (rule index #1) had an add_file flag, the user would still be unable to add a file because of the higher-precedence (though lower-index) deny rule.

Administering Permissions

You have a number of tools at your disposal for administering permissions. If you prefer the command line, you can use the commands chmod and chown. We must warn you though, because of the verbosity of access control entries, using chmod to apply ACEs can be a bit hairy.

The easiest way to manage ACLs on an OS X server is via the Server application. Then click the name of the server and then the Storage tab, as shown in Figure 4-3.

9781484217115_Fig04-03.jpg

Figure 4-3. OS X Server app screen: Storage tab

You can find the Server application inside the /Applications directory on any OS X server box, or any client onto which you’ve installed the Server app tools (available on the downloads section of Apple’s support web site). Once you have the application open, you can get to the File Sharing interface by highlighting the server container in the ServerList, and then clicking File Sharing. Here, you can browse your file systems or share points and assign both POSIX and ACL permissions. The Server app is a pretty good tool for modifying POSIX permissions, but it has no direct concept of execution. There is no way to set the execution bit exclusively using this tool; if you assign read privileges to a folder, it will include execution. When assigned to a file, the read permission includes only read, not execution. This probably isn’t a bad thing, as the number of scenarios where execution privileges need to be applied to files should be pretty rare, and the likelihood for human error would be high. Thus, the added consideration required to fire up a command line tool to grant execution rights to specific files isn’t necessarily a bad thing.

You can modify POSIX owners and groups by dragging them into the respective slots and then choosing the appropriate level of permission for each. To create ACLs for users and groups, drag them into the ACL list and apply appropriate permissions. Apple has several basic presets for you to use: Full Control, Read & Write, Read Only, Write Only, and Custom. Table 4-2 illustrates these privilege mappings when applied to files and directories.

Table 4-2. ACE Permissions Mapping

Permission

File System Object

Rights

Full Control

Directory

list, add_file, search, delete, add_subdirectory, delete_child, readattr, writeattr, readextattr, writeextattr, readsecurity, writesecurity, chown, file_inherit, directory_inherit

Full Control

File

read, write, execute, delete, append, readattr, writeattr, readextattr, writeextattr, readsecurity, writesecurity, chown

Read & Write

Directory

list, add_file, search, add_subdirectory, delete_child, readattr, writeattr, readextattr, writeextattr, readsecurity, file_inherit, directory_inherit

Read & Write

File

read, write, execute, delete, append, readattr, writeattr, readextattr, writeextattr, readsecurity

Read Only

Directory

list, search, readattr, readextattr, readsecurity, file_inherit, directory_inherit

Read Only

File

read, execute, readattr, readextattr, readsecurity

Write Only

Directory

add_file, delete, add_subdirectory, delete_child, writeattr, writeextattr, file_inherit, directory_inherit

Write Only

File

write, delete, append, writeattr, writeextattr

The Server app allows you to define custom privilege sets, which allow you to assign rights based up four main categories, Administration, Read, Write, and Inheritance, which we discussed in the earlier section “Access Control Entries.” To modify these permissions, highlight the object in the Server app and then click the cog wheel icon and click Edit Permissions. This will bring up a utility window, as shown in Figure 4-4.

9781484217115_Fig04-04.jpg

Figure 4-4. Server’s Custom ACE rights

Once you have established permissions on a directory, it is important to note that they only affect that directory. If you establish an ACE that has inheritance properties, those properties will only be inherited on newly created objects. To establish your permissions on existing files and folders, you will likely want to propagate those permissions to existing files and directories. To do so, with the desired parent folder selected, click the widget menu and select Propagate Permissions. You will then be presented with a sheet allowing you to select which permissions to propagate. Choices include owner name, group name, owner privileges, group privileges, everyone privileges, and Access Control Lists.

On a collaborative sharepoint, there will be few cases where we would recommend propagating an owner name (migrating a user’s home directory is the primary use-case for that option). All other options can prove to be extremely useful when establishing permissions hierarchies. When propagating ACLs, all subfolders and files will contain an “inherited” ACL, an implicit ACL that it received based upon the directory in which it was contained. If you have propagated an ACL to a particular directory and you would like to change an ACE that was propagated, you must first make the ACE explicit. You can do this by selecting the directory in question, clicking the widget, and then selecting Make Inherited Entries Explicit. Once you have done so, you can modify or delete the inherited entries, and then further propagate those changes using the propagation tool.

Last but not least is the Server app’s Effective Permissions tool. This very useful utility allows you to examine permissions that can be effected to an individual user. To access the utility, select a directory in the Server app File Browser, by once again clicking the widget menu and selecting Show Effective Permissions Inspector. This will bring up the Effective Permissions window. To check a specific user’s access rights, just drag the appropriate user from the Users and Groups pane. As shown in Figure 4-5, the tool will define exactly which rights that user has to the specified directory.

9781484217115_Fig04-05.jpg

Figure 4-5. Server’s effective permissions tool

Using the Finder to Manage Permissions

It is also possible to manage permissions using the Finder’s Info pane, shown in Figure 4-6. However, this interface is fairly pared down, and the POSIX/ACL system is abstracted a bit. One major limitation is that it is not possible to change the POSIX owner or group. It is possible to change the mode for owner, group, and everyone class, but outside of that, you can only manage ACLs. For ACEs, the Finder uses the Read & Write, Read Only, and Write Only presets used by the Server app with one crucial change: they do not set any of the inheritance properties. It is possible to propagate permissions to enclosing items using the Finder (once again found under a similar widget menu), but the propagation still doesn’t set any inheritance properties. This means that newly created subdirectories or files will not inherit any ACEs that you establish through this procedure. This is a fairly significant limitation. If you are attempting to manage ACEs on an OS X client machine and wish for propagation, you’ll need to set the inheritance rights yourself using the command line.

9781484217115_Fig04-06.jpg

Figure 4-6. The Finder’s Sharing & Permissions window

Using chown and chmod to Manage Permissions

You may often find yourself managing permissions from the command line. There are a few primary command-line apps that you will use to do this: chown, chgrp, and chmod. To change POSIX ownership of a file or folder, you use the chown utility. Its syntax is fairly straightforward:

chown owner[:group] /path to file

If all you’re doing is changing ownership, you can omit the :group (the colon followed by the actual value for group). Alternatively, you can use the chgrp command, which has similar syntax, but you instead provide the desired group name in the place of a user. OS X won’t let just anyone change the owner of a file. To change ownership, you must either have been granted the chown ACL right or be running as root. However, even if you have been granted the chown ACL right, you will only be able to assume ownership of a file yourself. Only the root user can change the owner to a user other than itself. For example, the following command changes the owner of file /tmp/myfile.txt to emeraldedge:

chown emeraldedge /tmp/myfile.txt

If we also want to change the group owner of the file, we can use the following command, which assigns admin as the group owner. As with ownership, a user can only change the group owner to a group that the user is a member of.

chown emeraldedge:admin /tmp/myfile.txt

Tip  You can use the command chflags hidden /MyFolder to make a file or directory invisible. When you run it, the folder will no longer be displayed in the Finder, though it will still be visible from command-line tools such as ls. To make these items invisible also from the command line, you can deny the readattr right.

You can use chmod to manage both POSIX and ACL permissions. Understand, however, that managing ACLs from the command line can be a bit hairy. It’s not for the faint of heart. Having said that, let’s walk through some of the basics.

As discussed a bit earlier, you can use chmod to modify POSIX permissions. The syntax is

chmod [-R] mode /path to file

The –R option, if used on a directory, applies the mode recursively to all descendants. To modify or create an ACE using chmod, you would use the +a, and –a flags. For instance, to grant full control of the file test.txt to the user emeraldedge, run the command:

chmod +a "emeraldedge allow read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,writesecurity,chown" test.txt

Subsequently, as discussed earlier, you can view the ACLs on that file by passing the –e flag to ls as follows:

ls -ael test.txt
-rw-r--r--+ 1 emeraldedge staff 0 Jul 9 00:56 test.txt
0: user:emeraldedge allow read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,writesecurity,chown

Likewise, if you want to grant full control of a directory, run this command:

chmod +a "emeraldedge allow list,add_file,search,delete,add_subdirectory,delete_child,image
readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown,image
limit_inherit,only_inherit" testfolder

To remove an entire ACE, you can use the –a# flag followed by an index number, as shown in the first example next. Or, if you wish, you can remove only specific attributes as shown in the second command, which removes only delete privileges, leaving the others in place.

chmod –a# 0 test.txt
chmod –a "emeraldedge allow delete"

When first applying ACLs or when making changes, you’ll likely want to propagate these changes to existing files and folders, because inheritance rules apply only at file- or folder-creation time. You can apply permissions recursively via the chmod –R +a command, but we’d recommend that you do this in the Server app via the Propagate Permissions menu item, which you can find by clicking the widget, shown previously in Figure 4-6 directly to the right of the pencil icon, a bit above the bottom of the screen. With this method, descendant file system objects will receive inherited, rather than explicit permissions.

When a large portion of your file system contains explicit permissions, management becomes harder. In addition, explicit permissions override implicit permissions, so you might end up with unexpected results. More care must be taken when managing such a model.

You can create inherited ACEs with chmod as well, which can be very useful. You do so by using the +ai flag instead of the +a flag. For example, the following commands will set a noninherited ACE on /MyAwesomeFolder, but will then recursively copy inherited ACEs to all descendants:

chmod +a "emeraldedge allow read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,writesecurity,chown" /MyAwesomeFolder
chmod –R +ai "emeraldedge allow read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,writesecurity,chown" /MyAwesomeFolder/*

Tip  Because of the way the chmod utility parses the ACE, using the traditional syntax for chmod ACLs does not work correctly when used with user or group names that contain spaces in the short name. This is primarily an issue in Active Directory environments, where user and group names routinely contain spaces. Fortunately, to get around this issue, you can use the colon as the user and rights delimiter. So, to assign an ACL for the group MYCOMac Server Admins, the following syntax can be used:

chmod +a ’MYCOMac ServerAdmins:allow:read,write, execute’ /MyAwesomeFolder

If you do a lot of ACL management from the command line, you may wish to save the common access rights as a shell variable so that you don’t have to type them out every time. To do this using The OS X default bash shell, you can simply add the following lines to your .bash_profile file, found directly inside your home directory:

export ACEFULLCONTROL="read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,writesecurity,chown,file_inherit,image
directory_inherit"
export ACEREADWRITE="read,write,execute,delete,append,readattr,writeattr,image
readextattr,writeextattr,readsecurity,file_inherit,directory_inherit"
export ACEWRITEONLY="write,delete,append,writeattr,writeextattr,file_inherit,image
directory_inherit"

Once you have saved this file, open up a new shell or reprocess your .bash_profile (run the command . ~/.bash_profile) file to establish the new variables. Once that is done, you can establish various ACE controls with the following example commands:

chmod +a “user:professorbrown allow $ACEFULLCONTROL” Hand-Ins
chmod +a “group:comm101students deny $ACEWRITEONLY” Course Files
chmod +a “group:comm101students allow $ACEREADANDWRITE” Public

You can also remove all of a file or directory’s ACEs via the chmod –N syntax. Combined with –R, you can use chmod to recurse through directories and remove all ACLs. For instance, to remove all ACEs on the Public folder, as well as nested items, the command syntax is chmod –RN Public.

The Hard Link Dilemma

One common issue faced with file system security is related to a low-level file system capability known as hard links. A hard link in generic terms is a legal occurrence of the same file on a file system in multiple directories. When created, a hard link serves simply as a reference to an existing file, and the link maintains the exact same attributes as its source file. Thus, if ownership, mode, or even the containing data is changed on a link, those exact same changes will be realized on the source file. In OS X, and indeed most POSIX-compliant systems supporting hard links, a user can create a hard link to any file to which they have read access, as long as they have write access to the destination that they specify, and that destination resides on the same file system as the source file. Because in most default OS X environments a user will have at least some file system path to which they have write access, this can present a fairly significant security issue.

For instance, consider a user who logs into a system and has a local home directory on that system. Next, consider all of the various system configuration files, which have world-readable access (hint: take a look at /etc/). Through the use of hard linking, a user with a shell account and a home directory can potentially exploit any of these world-readable files. To do so, they simply create a hard link to the file in their own home directory, using the ln command as shown here:

ln /etc/crontab ~/Public/Drop Box/crontab

In this particular case, the user is creating a hardlink on the file /etc/crontab in their Dropbox folder. This folder is chosen specifically because it has historically proven to be handled insecurely by system administrators who do not fully understand how to manage POSIX or ACL permissions. In some cases, to promote collaboration, administrators will run scheduled scripts to change ownership on a directory. After all, user Leroy needs to be able to modify all files in his drop box, so why not just routinely make him the owner of everything added to this folder? Well, as we can see if we have a hard link in that folder, suddenly that routine script isn’t quite so innocuous: with the linked file present in this directory, it, too, will be affected by the ownership change. Because, as we learned, hard link files share all file attributes, the net result is that the crontab file at /etc/crontab will now have the ownership changes applied to it as well. Suddenly this user has the ability to modify our crontab files, which means they have the ability to create schedule tasks that can operate under any user of their choosing, including root. Combine the privilege change with the fact that corn does no ownership checks on the file, and the net result is that the user now has complete access to the system—a major compromise.

Note  Although typical OS X command-line tools do not allow for creating hard links of directories, the OS does support it, and thus users can use lower-level tools such as Python or Perl to create hard links to attack entire directories in a similar fashion.

How do we defend against such an attack? Well, one key thing to know is that hard links can only be created when the source and the destination reside on the same volume. Thus, a very easy measure to ensure system stability against hard link attacks is to ensure the separation of system data and user data via separate file systems. That is, if a user’s directory does not reside on the same file system as system data, they will be unable to create a hard link to a system configuration file. Separation of user and system data in such a matter is a security and operational fundamental that should be routinely honored.

If you employ a network home directory model, then you are already provided some protections here, as the user’s home directory will not reside on the same file system as any system data. The problem, though, is still present when used in a collaborative environment. In such a case, a user may have read-only access to a particular file. By hard-linking the file to their home directory, they may be able to take advantage of any administrative tasks that deploy file system privilege modifications (whether manual or automated) to ultimately gain write access to the file. Fortunately, when a user creates a hard link, the attributes of the source file will be directly inherited from the source: any POSIX or ACL inheritance that would normally be applied to a new file will not be applied to a linked file. The security of the file remains intact: the user will have no access capabilities to the linked file that they don’t have to the original. Thus, hard linking in itself is not dangerous. The danger comes if any administrative routines are applied to the link, and thereby the source.

So how do we protect against this? Well the truth of the matter is that there isn’t a great way to protect against all possible misuses of hard links. The most approachable solution is to present access to collaboration data via protocols that do not support hard linking. For instance, neither the SMB nor the AFP protocol support hard links in default OS X configurations. Thus, any collaborative shares presented via these protocols are immune to such hard link attacks. Presenting collaborative data via a network protocol isn’t always an option, however, as sometimes collaboration will need to reside on a local volume. This might be, for example, an Xsan volume. In such a case, your best form of protection is to first avoid running administrative scripts that globally grant write provisions to files: lay down your file system hierarchy and a good inheritance model from the get-go, and you can avoid having to run such routines against the data. This certainly isn’t a complete answer, though. Another step would be to restrict the user from utilizing tools that can be used create links. At an extreme level, this would include preventing the user from accessing a shell altogether, as well as access to AppleScript capabilities. If the user must absolutely have shell access, an alternative approach would be to utilize OS X sandboxing to restrict access to certain CLI utilities: most notably /bin/ls, but also interpreted runtimes such as Python, Perl, PHP, or Ruby. Utilizing sandbox technology to protect an OS X environment is covered in detail in Chapter 6.

Using mtree to Audit File System Permissions

If you are reading this book we assume you have sensitive data to protect, and if so, you might want to consider routinely auditing your file system permissions. Earlier in this chapter, we learned of the risks that can be incurred when permissions are poorly applied. An inadvertent write mode granted to a directory containing executables means that a malicious user can inject her own executables, thereby granting her the ability to further exploit your system. The suid bit, when granted to an insecure program, can lead to a user subverting the program and gaining complete control of your box. If an executable must be suid to function, then there’s not much you can do with POSIX or ACL permissions to prevent damage. To protect against such a scenario, consider sandboxing your program, as discussed in Chapter 6.

However, one thing we can do is make sure that our intended permission structures maintain integrity. To do this, we can routinely audit our hierarchies to ensure that there are no unknown changes, and that even the files themselves have not changed. This can be used to ensure, for instance, that someone has not hijacked a program in your path and injected their own version. Fortunately, OS X includes by default a powerful tool for performing such an audit: mtree. Located at /usr/sbin/mtree, this command can be used to generate a specification file that contains information about the provided file system hierarchy. This specification can then be later referenced for comparison against the live file system. Any changes to the current structure from the specification will be reported. mtree provides the user the ability to specify the attributes to query and compare when running. Keywords can be specified to control exactly which statistics are saved to the specification and then which stats to compare with on the live file system. Though it is not an exhaustive list of mtree’s keywords, we should make note of the following important attributes:

  • gid, gnam: The file group as a numeric value.
  • md5digest: The MD5 message digest of the file. Specifying this keyword will ensure that an md5digest of each file is written to the specification. If the file is modified, it will modify the file’s digest, and therefore our routine audits will notify us of changes in the file. Because of potential weaknesses found in the MD5 algorithm, use of the sha1digest isn’t a bad idea.
  • sha1digest: The SHA-1 message digest of the file. This is more secure but also more CPU-intensive than md5digest.
  • mode: The current file’s permissions as a numeric (octal) or symbolic value. Monitoring this attribute will help detect any changes to POSIX permissions on the file.
  • uid, uname: The file owner as a numeric value and as a username, respectively. Monitoring these values can help to detect changes in directory services that might otherwise affect access.
  • size: The size, in bytes, of the file. Monitoring this value can help detect if any changes are made to the file itself.
  • link: The path that the symbolic link references. A symbolic link can be exploited by linking to a malicious program. Monitoring this keyword can help to detect such problems.
  • time: The last modification time of the file.
  • type: The type of the file. This keyword detects the type of object that is at a given path, such as a file, directory, a disk or network mount.

Note  mtree as of version 10.6 does not support ACLs or other extended attributes. Changes made to either will not be detected when performing mtree audits. Depending upon your scenario, you may want to write a custom script to audit or apply appropriate permissions.

With these keywords in mind, let’s venture into creating a specification file for comparison. To generate a spec file, we simply call mtree with the –c flag, and then point it to a path to reference for the specification with the –p flag. We use the –k flag to specify our desired keywords. And thus, the following command is born:

/usr/sbin/mtree –c -k ’gid gname -K sha1digest mode uid uname link image
type time’ –p /usr/bin > /Volumes/mtree_spec_files/myFreshSpec.txt

In this command, we specify our desired keywords and then create a specification based on the path /usr/bin. When it is run, mtree writes the specification to stdout. We capture this and redirect it to the file at path /Volumes/mtree_spec_files/myFreshSpec.txt. Preferably, once the file is written, it is then placed into a read-only state, safe from alteration or subterfuge. Once this specification file is in a secure place, preferably a read-only network mount, we can then reference it to audit the active environment. To do this, we call mtree with the following syntax:

/usr/sbin/mtree -f /Volumes/mtree_spec_files/myFreshSpec.txt -k ’gid gname image
sha1digest mode uid uname link type time ’-p /usr/bin
        modification time expected Mon Jan 25 00:29:27 2015 found Mon Jan 25 01:16:14
tar changed
        modification time expected Mon Jan 25 00:29:27 2015 found Mon Jan 25 01:16:14
        link_ref expected bsdtar found /tmp/XEOSUHEJOUE/t4Rpwn4g3

When run with this syntax, mtree will output any detected change made since the specification file was generated. In this case, we see that the object at path /usr/bin/tar has been relinked to a suspicious file located at /tmp/XEOSUHEJOUE/t4Rpwn4g3. Armed with this knowledge, we can repair the compromised link and begin to investigate the seriousness of the breach and the vector of the exploit.

Tip  In highly sensitive environments, it may be desirable to compile a custom copy of mtree to run from read-only media. This ensures that your auditing tool itself cannot be compromised.

Consider scheduling routine checks against critical directories on your system to warn you of any issues. The default system path is a good place to start here: /usr/bin:/bin:/usr/sbin:/sbin. If you have installed programs at /usr/local, you may also want to monitor that hierarchy. The /etc/ folder also contains important configuration files that you may want to monitor for modification.

If your systems contain valuable or sensitive data, then it is always a good idea to audit your system’s security. Through the mtree binary, OS X provides a built-in tool that does a pretty good job of accomplishing this. The mtree tool certainly isn’t as extensive as tools such as Tripwire, but it does its job well and is fairly easy to use.

Summary

In this chapter, we discussed the various tools and facilities that are provided in OS 10.11 to allow for the management and provisioning of data access provided through the file system. You should have a good fundamental understanding of both POSIX and ACL permission schemes, and you should have enough knowledge to apply them for use in your collaborative environment. We also discussed using the mtree tool for auditing file system permissions and structures to help guarantee system integrity and peace-of-mind.

In the next chapter, we will discuss various logging facilities that can be used for tracking historic data, useful in forensics and nonrepudiation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset