This post requires basic understanding of Unix File system permissions.
Permissions of new files and directories
Have you ever wondered how the permissions are chosen for newly created files and directories?
Let's assume the following example that creates a new directory named
somedirectory and a new file called
mkdir('somedirectory'); file_put_contents('examplefile', 'somedata')
What permissions will these files have?
Answer: It depends!
It depends on the processes umask environment.
What is the umask?
The umask is the file mode creation mask. The mask is applied with a bit wise operation whenever a file is created.
It is represented in logic notation as:
C: (P&(~Q))This says that the file's permission mode (
C) is a result of a logical AND operation between the negation of the mask (
Q), and the process' requested permission mode setting (
New files are requested with permission mode
666, directories with permission mode
Given we have a umask of
022 as octal value and we create a new file the following permissions are calculated:
Requested File permissions: 666 (P) Umask: 022 (Q) 666 & ~(022) = 644 (C)
umask 000 will allow read, write, and execute permission for all. This is a potential security risk and should not be used in production.
$ umask 000 # set umask $ mkdir testdirectory # create new directory $ touch somefile # create new empty file $ ls -l # list file permissions drwxrwxrwx testdirectory # 777 in octal -rw-rw-rw- somefile # 666 in octal
777 & ~(0) = 777 666 & ~(0) = 666
umask 002 will allow allow read, write, and execute permission for the user and the group, others will only have read access.
$ umask 002 $ mkdir testdirectory $ touch somefile $ ls -l drwxrwxr-x testdirectory # 775 in octal -rw-rw-r-- somefile # 664 in octal
777 & ~(002) = 775 666 & ~(002) = 664
umask 077 Is the most restrictive umask. Only the user has access to the generated files.
$ umask 077 $ mkdir testdirectory $ touch somefile $ ls -l drwx------ testdirectory # 700 in octal -rw------- somefile # 600 in octal
777 & ~(077) = 700 666 & ~(077) = 600
Umask in PHP
PHP respects the umask even if the mkdir
$mode parameter is set:
umask(0027) // set directly or by environment $mode = 0775; mkdir('somedirectory', $mode);
Given we have a umask of 027 this will result in the following permission:
775 & ~(027) = 750
chmod() on the other hand does not respect the umask.
umask(0027) // set directly or by environment $mode = 0775; chmod('somedirectory', $mode);
This will result in
775 permissions regardless of the umask setting of the process.
Umask in shopware
Shopware already respected the umask for some caches. Some other caches used hard coded permissions.
The Smarty Compile Cache for example used hard coded permission values:
// file engine/Library/Smarty/Smarty.class.php public $_file_perms = 0644; public $_dir_perms = 0771;
This is now changed to respect the umask:
// file engine/Library/Enlight/Template/Manager.php $this->_file_perms = 0666 & ~umask(); $this->_dir_perms = 0777 & ~umask();
Also the permissions of cache files are now using the umask instead of hard coded permissions:
// file: engine/Shopware/Configs/Default.php 'cache' => [ 'backendOptions' => [ - 'hashed_directory_perm' => 0771, - 'cache_file_perm' => 0644, + 'hashed_directory_perm' => 0777 & ~umask(), + 'cache_file_perm' => 0666 & ~umask(), ] ]
You can find all the changes in the Github Pull Request.
This changes will be included in the upcoming Shopware 5.1.4 release.
Setting the umask
Now that Shopware respects the umask for all cache files there no need to configure individual file creation permissions anymore.
Just set the umask and Shopware will create files accordingly. The umask can be set in your Apache or PHP-FPM configuration, or by calling
umask(0077); in you projects