Difference between revisions of "Setting Default File Permissions"

From PHASTA Wiki
Jump to: navigation, search
Line 1: Line 1:
 
This page will review how to set default file permissions for a directory. This is often used when working in HPC "scratch" directories where members of the same research group (like us) want to give each other some default file permissions on every file created in those directories, regardless of who created them.
 
This page will review how to set default file permissions for a directory. This is often used when working in HPC "scratch" directories where members of the same research group (like us) want to give each other some default file permissions on every file created in those directories, regardless of who created them.
  
 +
The basis of this is to edit the ACL entries of the directories that we want default file permissions to apply to. To see more information on how ACL and file permissions work, see [[File_Permissions_Basics_and_ACL|File Permissions Basics and ACL]].
  
== Basics of Unix/POSIX File Permissions ==
 
  
=== What are they? ===
+
== Setting ACL Rules ==
  
* All files and directories have permissions assigned to them
+
For most POSIX file systems, this can be done via <code>setfacl</code> ([https://linux.die.net/man/1/setfacl see manpage here]). For fancier filesystems, you may need to use other commands/tools to perform the same effective operation.
* All files and directories have a designated user and group "owners", known as file owner and file group respectively
 
** By default, these are the ones that created the directory/file, but this can be changed using `chown`
 
* There are three different "levels" of file permissions in a standard POSIX: read (<code>r</code>), write (<code>w</code>), and execute (<code>x</code>).
 
** Read allows viewing the contents of the file/directory, and copying the files
 
** Write allows rewriting and deleting files. For a directory with write permissions, it also allows creation of subdirectories and creation of new files
 
** Execute allows files to be executed directly.  
 
*** Note that for script files (such as <code>bash</code> or <code>python</code>), they can still be run by passing the file to it's interpreter if the file is readable (ie. <code>bash non_executableScript.sh</code> is still possible if <code>non_executableScript.sh</code> has <code>rw-</code> permissions).
 
* These different levels of file permissions are assigned to three different groups of users: file owner, file group, and "others".
 
** "Others" simply refers to any users that don't fall into the other two categories
 
* The file permissions for these three categories form the file <code>mode</code>
 
  
==== Viewing them ====
+
To set a ACL entry, use the <code>-m</code> to ''modify'' the given entry. The format for the ACL entry is identical to what is displayed when running <code>getfacl</code> on a file. Generalized, it takes the form:
As an example, if you run <code>ls -l</code> on a directory, you might see:
 
  
  drwxr-x---+ 2 jrwrigh7 a1983 4.0K 2020-07-04 08:09 test2
+
  [d[efault]:] [(u[ser]|g[roup]|m[ask]|o[ther]):](uid|gid|) [:perms]
-rw-r-x---+ 1 jrwrigh7 a1983  38 2020-07-02 12:38 test2file
 
lrwxrwxrwx  1 jrwrigh7 a1983    9 2020-07-04 08:40 test2fileLink -> test2file
 
  
 +
=== Examples ===
  
The first block (<code>-rw-r-x---+</code>) shows the permissions for the file (described below). The user owner is shown as <code>jrwrigh7</code> and the group owner is <code>a1983</code>.
+
Using the user ID <code>sfseiei</code> and group ID <code>meisters</code>
  
'''Permissions Block:'''
+
'''Give a user read access to a file object:'''
* First character displays what kind of file it is, be it a link (<code>l</code>), directory (<code>d</code>), regular file (<code>-</code>), etc.
+
setfacl -m u:sfseiei:r fileobj
* The next 9 characters show the permissions for the file owner, file group, and "others".
 
** So for <code>test2file</code> in the above output:
 
*** File Owner: <code>rw-</code>
 
*** File Group: <code>r-x</code>
 
*** Others: <code>---</code>
 
* The last character is optional. A <code>+</code> means that there are other permission rules not displayed. This is where [[Setting_Default_File_Permissions#Setting ACL Rules|ACL rules]] come into play.
 
  
See [https://www.gnu.org/software/coreutils/manual/html_node/What-information-is-listed.html#What-information-is-listed the ls coreutils manual] for more information on the 'long' format for <code>ls</code>.
+
'''Give a group read and write access to a file object:'''
 +
setfacl -m g:meisters:rw fileobj
  
==== Octal numbers ====
+
'''Give a group read and write access to a directory and it's contents recursively'''
The file <code>mode</code> is often conveyed in the form of three octal numbers (ie. base 8 numbers). It is very similar to how PHASTA handles specifying boundary conditions using bitwise logic.
+
setfacl -R -m g:meisters:rw directory
The first bit handles read, the second bit handles write, and the third handles execute.
 
  
Using <code>test2file</code> as the example permissions block, it is stored as <code>110 101 000</code>. When translated into decimal, that equals <code>3 5 0</code>.
+
* The <code>-R</code> flag is used for recursively applying the ACL entry
  
Another way to think about it is that the octal number equivalent of a permission set = 1*r + 2*w + 4*x, where r, w, and x equal 0 or 1 depending on whether they're set.
+
: ''Note that any new files created in this directory or subdirectories will '''not''' be readable or writable by members of the group''
  
=== What determines the permissions for a new file? ===
+
'''Give a group read and write access to a directory, it's contents, and have new files inherit these rules'''
 +
setfacl -Rd -m g:meisters:rw directory
  
There are three sources that determine what file permissions will be set; <code>umask</code>, the "mode" parameter used by the program creating the file, and ACL.
+
* The <code>-d</code> flag denotes that the changes should be added as a ACL default entry.
 +
** This makes any new files inherit these ACL default entries, '''but''' does not necessarily mean that they will be effective. See [[Setting_Default_File_Permissions#Common "Gotchas"|Common "Gotchas"]]
 +
* See [[File_Permissions_Basics_and_ACL#Custom Permissions| Custom Permissions]] for more information on the importance and function of ACL default entries.
  
==== umask ====
+
== Common "Gotchas" ==
  
<code>umask</code> is a function that contains file permission settings for any file created by a user and it is unique to the user. The user can change it at anytime using the <code>umask</code> command. To see what it is set to, simply run <code>umask</code> with no arguments.
+
=== Newly Created File Only Doesn't Fully Inherit Default ACL Rules ===
  
==== "Mode" Parameter ====
+
tl;dr ACL Default entries are not the only thing that controls the permissions of new files. See [[File_Permissions_Basics_and_ACL#Custom Permissions| Custom Permissions]] for deeper explanation.
  
When a new file is created, the <code>syscall</code> <code>open()</code> (among others) is used and a file mode parameter must be chosen by that program. For example, `touch` will automatically apply the mode <code>666</code> to the file, which will make the file owner, file group, and "others" all have <code>rw-</code> permissions
+
This is probably most common with files that don't inherit the executable permission from the default ACL. In [[File_Permissions_Basics_and_ACL#How are new file permissions set?| How are new file permissions set?]], it is explained that the <code>ACL_MASK</code> (among others) will be set such that the resulting ACL permissions do not exceed the permissions set by the "mode" parameter (which is used by the program creating the file). Often, this "mode" parameter does not include execute permissions (with the primary exception being compilers, which will set binaries with execute permissions).
  
==== ACL Defaults ====
+
This is normal behavior and can always be overridden with `chmod`.
  
The Access-control List (ACL) has the ability to set more nuanced permissions for files (ie. permissions for specific users or groups that are not file owner or file group). They can be set for a specific file/directory, or as a ''default'' setting. This default setting is set for a directory and is used for files and subdirectories created inside that directory.
+
'''Example:'''
  
There are 6 different tags that ACL rules can apply to. From the <code>acl</code> manpage:
+
I have a directory with the following ACL entries:
 +
$ getfacl .
 +
# file: .
 +
# owner: jrwrigh7
 +
# group: a1983
 +
user::rwx
 +
group::r-x
 +
group:a1983:r-x
 +
mask::r-x
 +
other::---
 +
default:user::rwx
 +
default:group::r-x
 +
default:group:a1983:r-x
 +
default:mask::r-x
 +
default:other::---
 +
: Note that all the <code>default:</code> entries have execute permissions except <code>other</code>
  
ACL_USER_OBJ    The ACL_USER_OBJ entry denotes access rights for the file owner.
+
I'll create new file in that directory using `touch`:
+
  $ touch testfile
ACL_USER        ACL_USER entries denote access rights for users identified by the entry's qualifier.
 
 
ACL_GROUP_OBJ  The ACL_GROUP_OBJ entry denotes access rights for the file group.
 
 
  ACL_GROUP      ACL_GROUP entries denote access rights for groups identified by the entry's qualifier.
 
 
   
 
   
  ACL_MASK        The ACL_MASK entry denotes the maximum access rights that can be granted by entries of type ACL_USER, ACL_GROUP_OBJ, or ACL_GROUP.
+
  $ getfacl testfile
   
+
  # file: testfile
  ACL_OTHER      The ACL_OTHER entry denotes access rights for processes that do not match any other entry in the ACL.
+
# owner: jrwrigh7
 
+
  # group: a1983
<code>ACL_USER_OBJ</code>, <code>ACL_GROUP_OBJ</code>, and <code>ACL_OTHER</code> correspond to the file owner, file group, and "other" permissions mentioned above and shown by <code>ls -l</code>. The other two (<code>ACL_GROUP</code> and <code>ACL_USER</code>) are for custom permissions.
+
user::rw-
 
+
group::r-x                      #effective:r--
The <code>ACL_MASK</code> entry plays an important role in [[Setting_Default_File_Permissions#How are file permissions set?|how new file permissions are set]].
+
group:a1983:r-x                #effective:r--
 
+
mask::r--
=== How are new file permissions set? ===
+
other::---
The manpage for ACL is a great resource to answering this question. Most of the information below is simply paraphrasing what is written in the "Object Creation and Default ACLs" section.
 
 
 
When creating a file/subdirectory in a parent directory:
 
 
 
* If the parent directory '''does have default ACL rules''', only the ACL default rules and "mode" parameter are used:
 
** The new file/subdirectory first inherits the default ACL rules of its parent directory
 
** The new file/subdirectory has its ACL entries adjusted such that no permissions exceed the "mode" parameter.
 
*** The <code>ACL_USER_OBJ</code> and <code>ACL_OTHER</code> are changed directly
 
*** The <code>ACL_GROUP</code>, <code>ACL_GROUP_OBJ</code>, and <code>ACL_USER</code> are changed ''through'' adjusting the <code>ACL_MASK</code>
 
** Additionally, if a new subdirectory is created, it will inherit its parents default ACL rules. Note that a file ''cannot'' have default ACL rules set.
 
  
* If the parent directory '''does not have default ACL rules''', only <code>umask</code> and "mode" parameter are used:
+
We see that the file did inherit the <code>default:</code> ACL entries for <code>group::</code>, <code>group:a1983:</code>, and <code>other::</code>. However, the <code>mask::</code> and <code>user::</code> are different than its corresponding <code>default:</code> value.
** The new file/subdirectory's <code>ACL_USER_OBJ</code>, <code>ACL_GROUP_OBJ</code>, and <code>ACL_OTHER</code> are set based on the permissions set by <code>umask</code>
 
** The new file/subdirectory's are then adjusted to limit permissions to be no looser than the "mode" parameter
 
  
Note that this all means that if you have a default ACL rule that gives execute permissions to a group, the group will not have execute permissions by default ''unless'' the "mode" parameter also has execute permissions. Most compilers will use the execute permission bit for the "mode" parameter of it's executable, but other files will not.
+
This is because <code>touch</code> uses a "mode" parameter of <code>666</code> when creating the new file object (<code>6</code> translates to <code>-wx</code>, see [[File_Permissions_Basics_and_ACL#Custom Permissions| Custom Permissions]]
 
 
== Setting ACL Rules ==
 

Revision as of 20:34, 6 July 2020

This page will review how to set default file permissions for a directory. This is often used when working in HPC "scratch" directories where members of the same research group (like us) want to give each other some default file permissions on every file created in those directories, regardless of who created them.

The basis of this is to edit the ACL entries of the directories that we want default file permissions to apply to. To see more information on how ACL and file permissions work, see File Permissions Basics and ACL.


Setting ACL Rules

For most POSIX file systems, this can be done via setfacl (see manpage here). For fancier filesystems, you may need to use other commands/tools to perform the same effective operation.

To set a ACL entry, use the -m to modify the given entry. The format for the ACL entry is identical to what is displayed when running getfacl on a file. Generalized, it takes the form:

[d[efault]:] [(u[ser]|g[roup]|m[ask]|o[ther]):](uid|gid|) [:perms]

Examples

Using the user ID sfseiei and group ID meisters

Give a user read access to a file object:

setfacl -m u:sfseiei:r fileobj

Give a group read and write access to a file object:

setfacl -m g:meisters:rw fileobj

Give a group read and write access to a directory and it's contents recursively

setfacl -R -m g:meisters:rw directory
  • The -R flag is used for recursively applying the ACL entry
Note that any new files created in this directory or subdirectories will not be readable or writable by members of the group

Give a group read and write access to a directory, it's contents, and have new files inherit these rules

setfacl -Rd -m g:meisters:rw directory
  • The -d flag denotes that the changes should be added as a ACL default entry.
    • This makes any new files inherit these ACL default entries, but does not necessarily mean that they will be effective. See Common "Gotchas"
  • See Custom Permissions for more information on the importance and function of ACL default entries.

Common "Gotchas"

Newly Created File Only Doesn't Fully Inherit Default ACL Rules

tl;dr ACL Default entries are not the only thing that controls the permissions of new files. See Custom Permissions for deeper explanation.

This is probably most common with files that don't inherit the executable permission from the default ACL. In How are new file permissions set?, it is explained that the ACL_MASK (among others) will be set such that the resulting ACL permissions do not exceed the permissions set by the "mode" parameter (which is used by the program creating the file). Often, this "mode" parameter does not include execute permissions (with the primary exception being compilers, which will set binaries with execute permissions).

This is normal behavior and can always be overridden with `chmod`.

Example:

I have a directory with the following ACL entries:

$ getfacl .
# file: .
# owner: jrwrigh7
# group: a1983
user::rwx
group::r-x
group:a1983:r-x
mask::r-x
other::---
default:user::rwx
default:group::r-x
default:group:a1983:r-x
default:mask::r-x
default:other::---
Note that all the default: entries have execute permissions except other

I'll create new file in that directory using `touch`:

$ touch testfile

$ getfacl testfile 
# file: testfile
# owner: jrwrigh7
# group: a1983
user::rw-
group::r-x                      #effective:r--
group:a1983:r-x                 #effective:r--
mask::r--
other::---

We see that the file did inherit the default: ACL entries for group::, group:a1983:, and other::. However, the mask:: and user:: are different than its corresponding default: value.

This is because touch uses a "mode" parameter of 666 when creating the new file object (6 translates to -wx, see Custom Permissions