Understanding File Permissions on Linux


When configuring file sharing within your network, a good understanding of basic file and directory permissions is necessary regardless of the Operating System being used. One of the biggest obstacles administrators face is the fact that (by default) Linux Operating Systems utilize more "secure" file and directory permissions by default. This is different than the "Everyone has read/write access" defaults of Microsoft Windows based Operating Systems. Because of these differences, many administrators coming from a Windows background find it frustrating and confusing to configure file sharing with Linux. (Also because of this, most Windows servers have very insecure file and directory permissions on their shares as most admins don't bother to change them from the defaults).

With Linux, file and directory permissions are separated into two parts: basic file permissions and ACLs (Access Control Lists). All Linux distributions (and all applications) abide by basic permissions, but unfortunately, not all Distributions and applications have support for ACLs (although this is changing). In most cases (when dealing with Linux Clients) it is wise to simply use basic file permissions and only utilize ACLs when absolutely needed and when you know all applications will support them (without overriding them). This section will hopefully show you how to easily utilize basic file permissions for most deployments and touch upon ACLs for special cases that you may encounter.

Basic Permissions

Linux Operating Systems allow you to provide basic permissions for every file and directory depending upon if you are the "Owner" of the file/directory, are in the same "Group" as the "Group Ownership" of the file/directory, or if you are simply "Others" (meaning everyone else). The basic rights that you can change for these permissions are "Read", "Write", and "eXecute", where:

For Files:

  • "Read" means to be able to open and view the file
  • "Write" means to overwrite or modify the file
  • "eXecute" means to run the file as a binary

For Directories:

  • "Read" means to be able to view the contents of the directory
  • "Write" means to be able to create new files/directories within the directory
  • "eXecute" means to be able to "Change Directory" (cd) into the directory
  • Most of the time you set "Read" and "eXecute" together on directories (kind of useless when set by themselves)

To view the permissions of files and directories you can utilize the Command Line program "ls" with either the "-l" or the "-dl" options.

Viewing File Permissions using the ls command

The output of the "ls -dl" command would be in the form:

   perms    D  owner     group  size   modified date    name
drwxr-xr-x  2 mpetersen company 4096 2007-07-10 13:43 fileperms
-rw-r--r--  1 mpetersen company 9698 2007-07-10 13:42 fileperms.html

Where "perms" are the permissions of the file/directory as 10 characters, the first character represents "special bits" (covered later) and the rest of the characters represent the rights of each "entity" using three characters - "rwx" for read, write execute. Such that a -rw-rw-r-- entry would indicate that the owner and group would have read-write privileges, while everyone else would only have read privileges.

A few words about Groups within Linux: By default when someone creates a new file, the Group Ownership of that file is specified as the users "Default Group". To access that file as another user, that user does not need to have the same "Default Group", that user only needs to be a member of the group listed as the "Group Owner" of the file.

Changing Permissions

To change permissions of files/directories here are a few commands that you can use:

  • chown - This will change the ownership of the file/directory (need to be root to use)
  • chgrp - This allows you to change "Group Ownership" of a file or directory
  • chmod - This allows you to change the "access rights" to the file or directory, such as:
    • chmod +rx filename* - will add read and execute permissions for the owner, group and others
    • chmod g+w filename - will add write perms to the group
    • chmod go-w filename - would remove write perms for the group as well as everyone else.

* Note the "chmod +w filename" command will only add write permissions for the owner and not the group or others (unlike a "chmod +rx filename" command).

Working with Numeric Permissions

An alternative to using the "g+rw" or "o-rx" options to the chmod command is to set permissions on files/directories using numeric options. This has the benefit of working very well with scripts. Also, if you know exactly what permissions you want on a file it can be quicker using the numeric options instead of the standard way. For instance:

chmod 660 filename

would be the equivalent of issuing:

chmod g+rw filename
chmod o-rw filename

When using numeric permissions, you specify the exact rights for every entity (owner, group, others) instead of adding or subtracting rights using "o-rw", etc. So if you simply want to add Group Write access to a file, it is easier to simply do a "chmod g+w filename" instead of figuring out the exact numeric rights you want to give the filename.

To figure out the exact numeric rights, use the following chart to equate the right with a number:

0     no access
1     eXecute
2     Write
4     Read

Then whatever rights you want to give the file/directory, you simply add up numbers for the rights. For example, if you want read and write privileges, you would add 2 and 4, which would give you 6, so if you want owner and group read/write access you would issue the following command: "chmod 660 filename".

Default Permissions on Linux

Most Linux Distributions, by default, will set the permissions on any new file/directory created to only be writable by the owner of the file/directory and give the group members and others read-only access (and eXecute privilege for directories). This may not be what you want when you are working on a network and try to collaborate with other people.

These default permissions are set by a command called "umask" and is automatically ran when you first log into the machine (although you can re-run this command at any time). The umask command takes a 3 digit number that is "subtracted" from the default permission value that Linux gives files and directories to come up with the default permissions for the system.

The "default" permission value that Linux sets on a file (without applying a umask) is "666" which would be the owner, group and others have read-write access to it. When you set a umask of "022" during login (most distributions use "022"), the default permissions for files then becomes "644" since the umask is subtracted from "666".

The "default" permission value that Linux sets on a directory (without applying a umask) is "777" (to allow eXecutable permissions to be set by default), and the umask is applied in the same manner as files.

So, when you are working with files over a network, it is probably a good idea to change the umask to either "002" which would allow owner and group members to have writable permissions and others to have read-only permissions, or to "007" which would do the same as the previous example, but give others no permissions to the file or directory.

Once you figure out the umask you want to use, to set it within most Linux distributions you would adjust the /etc/profile file. However, with Suse Linux, you only need to create a new file named /etc/profile.local and add the following into it to adjust the default permissions:

   umask 002

Special Bits

So far, you have been shown the basic manipulation of file and directory permissions. However, there are quite a few circumstances which these will not be enough for the situation. For instance, what if you have a few people that have different "Default Groups", but are members of another group and you need them to all have write access to certain files. Or what if you have some less knowledgeable users that may accidentally delete other peoples files if they are given write access to a directory.

To rectify these situations, Linux provides what are called "Special Bits" that you can apply to files and directories to change their default behaviour.

The setuid Bit

The setuid (set user id) bit allows you to specify which user a certain program is executed as. This is not really useful for sharing files on a network, but can be invaluable when you have an application that needs to run as another user (such as 'root') when launched. An example:

chown root /usr/bin/myprogram
chmod +x /usr/bin/myprogram
chmod +s /usr/bin/myprogram   (this sets the setuid bit)

In the above example, whenever anyone launches the /usr/bin/myprogram application, the program will have all of the rights of the "root" user regardless who actually launched the file. (Use with Caution)

On the command line, an "ls -l" output of a setuid bit file would be:

-rwsr-xr-x 1 root root 11159 2007-07-16 12:09 myprogram

The setgid Bit

The setgid (set group id) bit can be the cornerstone of good file permissions. This bit allows you to enforce what group ownership a directory (and all it's subdirectories and files) have. For instance if you set the setgid bit to "admins" on a directory, any file (and directory) created below that directory will also have the "admins" group ownership. This allows you to setup a shared network folder that is accessible by any member of the group, and any file below that directory will maintain that group ownership (regardless of the user's primary group). Here is an example:

mkdir accounts
chgrp acctns accounts
chmod g+w accounts
chmod g+s accounts  (this sets the setgid bit)
chmod o-rwx accounts

In this example, any member of the acctns group will be able to access and write to the accounts directory, and since the setgid bit is set, any new file or folder created will have "acctns" as it's group ownership. This allows you to create a shared network folder for a specified group without having to make it "world writable".

Note: Any directory created within a setgid set directory will also be "setgid".

On the command line, an "ls -l" output of a setgid bit directory would be:

drwxrws--- 2 root company 48 2007-07-16 12:12 share

The Sticky Bit

The "sticky" bit (also known as the "Save Text Attribute" bit) is set only on a directory and specifies that only the owner of a file can delete their own file within the directory regardless of the group or other's "writable" status. So, in the setgid example, if you did not want any member of the "accts" group to be able to delete a file (unless they "owned" the file), then you would set the sticky bit on the accounts directory:

chmod +t accounts

On the command line, an "ls -l" output of a "sticky" directory would be:

drwxrws--T 2 root company 48 2007-07-16 12:12 share

Setting Special Bits using Numeric Permissions

As with regular file permissions, you can also use numeric permissions to set these special bits (useful when creating scripts). When setting special bits using numeric permissions, you would increase the number of digits from 3 to 4 digits (for instance, instead of 664 you would use 0644), where the first digit would set the special attributes.

Similar to regular permissions, you need to add the digits together using the following chart:

0     no special bit is set
1     sticky bit is set
2     setgid bit is set
4     setuid bit is set

So, if you want the sticky and the setgid bits set on a directory (as well as group full control and others no access) you would use 3770. For example:

chmod 3770 directoryname
ls -l
drwxrws--T 2 root company 48 2007-07-16 12:12 share

Working with Permissions

Now that you should have the basics of file permissions down, this section includes some "tips and tricks" that I use to ensure that permissions are properly set on servers.

Home Directories

Most admins overlook the setting of permissions on user's home directories. I believe, this is because most admins do not have a good understanding of Unix Permissions (especially those coming from a Windows background). Because of this, most Linux Servers are deployed with the default permissions in place, which are the owner has full permissions and everyone else has read permissions. This may not be what you want (everyone has the ability to read everyone else's files), and you should seriously look at home directory permissions before deploying any servers.

To fully understand what you can accomplish with home directories I am going to give an example that I used when deploying SLES at a local high school:

First, in order to maintain some sort of organization, the school decided to separate out the home folders into the student's graduation year. So within the "/home" directory, there were directories "2008", "2009", "2010", "2011", etc. for all of the student's home directories. There were also directories called "teachers", "staff" and "admins" to hold all of the staff's home directories.

Using separate containing directories for the user's home directories proved to be quite successful not only for organization purposes, but also to ensure that correct file permissions were enabled. For every student's home directory we adjusted the permissions to have the group ownership of the "teachers" group and we ensured that the teachers could write to the folders. We also ensured that the other students had no access to other student's files. For instance, to set permissions we ran:

cd 2009
chgrp teachers * -R
chmod g+w * -R
chmod g+s * -R
chmod o-rwx * -R

This ensured that the teachers had write permissions to the student's files, while ensuring that any new file that was created by the student had the "teacher" group as the group owner (using the setgid bit). We did this for all of the student's folders as well as all of the staff's folders (except we changed the group ownership to "sadmins" (Super Admins) instead of "teachers" for the staff).

Scripting File Permissions

Once you have a deployment strategy for file permissions, you may want to create a shell script to apply those permissions. This alleviates manually running a group of commands after you create a new user or when the permissions are not correct (which occasionally happens when "copying" files).

Using the above example of the school, here is a shell script that is ran as a daily cron job to ensure the permissions are correct:

# This script will reset permission's on home directories every night
cd /home
# First we will reset the permissions for the Student Folders.
# We store all of the students folders within their graduation year
# This makes it easy to sort the student's data
# The first loop changes into the student's graduation year directory
for grad_dirs in $(ls 20* -d); do
	cd $grad_dirs
# This next loop actually changes permission on all the student's files
#  and directories.
	for userlogin in $(ls); do
		cd $userlogin
		find -type d -exec chmod 2775 '{}' \;
		find -type f -exec chmod 664 '{}' \;
		install -m 0644 /var/defaults/.dmrc ./
		cd ..
		chown $userlogin $userlogin -R
# Finally, while we are still in the grad year directory, we change group
#  ownership of all the files and directories to the teachers. This allows
#  them full access to the students files and folders.  Before we exit the
#  graduation year directory we also remove "others" access to the student's
#  directory - this ensures students can't access other students data.
	chgrp teachers * -R 
	chmod 2750 *
	cd ..
# Now we will do the same thing for the Teachers and Staff Accounts, the
#  difference will be the group owner will be sadmins (Super Admins) instead
#  of teachers.  This will allow Teachers and Staff to store private data
#  in their home directories, while allowing Administrators to monitor their
#  disk usage and ensure no copyright material is stored on school property.
for staff_accounts in staff teachers
        cd $staff_accounts
        # Run the same loop as the student dirs above
        for userlogin in $(ls); do
                cd $userlogin
                find -type d -exec chmod 2775 '{}' \;
                find -type f -exec chmod 664 '{}' \;
		install -m 0644 /var/defaults/.dmrc ./
                cd ..
                chown $userlogin $userlogin -R
        chgrp sadmins * -R
        chmod 2750 *
        cd ..

As you can see in the above example it can be easy to ensure correct permissions are maintained on your shares. Another thing to note in the above example is the procedure used to change the permissions of items depending upon whether they are files or directories (since these two entities have different permissions - i.e. directories should be executable). So, if you copy files from a CD or another server, to ensure the permissions are "Unix Compatible" run something similar to:

cd directory
find -type d -exec chmod 755 '{}' \;
find -type f -exec chmod 644 '{}' \;

A Basic Network Share

Now I will put all this together and show how to create a network share that is fully accessed by members of the "company" group:

mkdir /srv/exports/share
chgrp company /srv/exports/share
chmod g+w /srv/exports/share
chmod o-rwx /srv/exports/share
cp /old/files/* /srv/exports/share -f -r
cd /srv/exports/share
chgrp company * -R
find -type d -exec chmod 2770 '{}' \;
find -type f -exec chmod 660 '{}' \;

Once that is done, if the share is accessed using NFS on Linux workstations, ensure the umask on those workstations is set to 002 or 007 (to ensure the "Group" has write access on new files), and if the share is accessed on Windows workstations, ensure the appropriate "masks" are set in the Samba Share definition.

Access Control Lists

Although basic file permissions will probably work for nearly all of your file share deployments, occasionally you might need the ability to "fine-tune" permissions for some network shares or files. You can accomplish this control by using Access Control Lists (ACLs) on your files and directories.

For this tutorial, I am not going to go into detail regarding ACLs. Although, it is easy to adjust and add ACLs from Linux using either the Konquerer file manager or the Nautilus file manager (with the eiciel plugin). You can even adjust ACLs using Windows Explorer (from remote Windows Workstations connecting through Samba). However, a word of warning is important: Not all GNU/Linux applications properly support ACLs (yet), if you deploy ACLs on Directories / Files accessed through NFS using SLED or another GNU/Linux Distribution, ensure that all of the apps that will access these shares properly support ACLs.

Finishing Up

Hopefully, after reading this you have a better understanding of Permissions within a GNU/Linux system. Once you develop a deployment plan, I highly recommend creating a script to ensure proper permissions are maintained on your servers. Linux file permissions may look too simplistic at first glance, but once you grasp the concept you will quickly see the ingenuity (and the power) behind them.

Google Ad

© 2017 Mike Petersen - All Rights Reserved