Giving PHP permission to write to files and folders

120,782

Solution 1

I will complete rahmu's and MV's answers with a technical solution. Everything that follows is valid for UNIX-like systems only.

Scroll past the chmod/chown section for an example using ACLs - a more powerful tool than UNIX file modes.

Finding your web server username

First, you will need to know the username under which your web server runs. If you are using Apache, it can be apache or httpd, www-data, etc. On most Debian-like systems, Apache is www-data. For nginx, generally, it is also www-data.

To check it out, try:

ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1

Ensure that the username this command returns is coherent (for example, I use nginx 99% of time, but this command returns tomcat7, a Java web server I installed once).


Giving permissions to the web server: using chmod and chown

Doing a chmod of 666 or 777 (the go-to solution for that kind of problems in bad documentations/tutorials) can magically make things work, but is insecure. Giving 666 or 777 permissions will give access to "others". So not just Apache, but also grandmother and nsa (provided that those user accounts exist on your machine - but no really, please avoid doing this unless it's just for testing/troubleshooting).

It is better to be more specific and give permissions to just you and Apache. Change the group of your files to give the full control on your files to the web server. To do this, change the owner recursively:

chown -R www-data:www-data your/folder/

But most likely, you may want to keep full access on your files by changing the group only:

chown -R yourusername:www-data your/folder/

Then, do the appropriate chmod to give the group www-data the same permissions as you. For example, if the current mode is 640 (6 for you, 4 for www-data, 0 for others, translating to -rw-r-----), set it to 660 (6 for you, 6 for www-data, 0 for others, translating to -rw-rw----). See rahmu's answer to learn more about file modes, it's an old, however elegant mechanism.

To avoid manipulating arcane numbers with chmod, you can also use this syntax:

chmod -R g+rw your/folder/

It means "to the group (g), add (+) read and write (rw) permissions on folder your/folder/, recursively (-R)".

In 90% of cases, this should be enough.


My preferred method: using ACLs (Access Control List)

Sometimes the first solution is not sufficient. I will take the example of Symfony Framework that logs and caches a lot of data. So it needs write access to the appropriate folder.

And the chmod/chown method may not be sufficient, when you are using in parallel the Symfony Console in CLI (under my user account) and the Web (web server user). This causes a lot of problems because Symfony is constantly modifying permissions.

In this case, we will use the ACL (Access Control List), which is a more advanced way to manage permissions on many UNIX systems.

Here the commands given by the official Symfony documentation (please change app/cache and app/logs to your needs):

On a system that supports chmod +a (ie. not Debian/Ubuntu)

sudo chmod +a "www-data allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs
sudo chmod +a "`whoami` allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs

On a system that does not support chmod +a (most common)

You will need the setfacl tool; maybe it is installed on your system by default, so try setfacl -v to see if the command is available.

If the command is not available, and you are using Ubuntu 14.04+, you'll just have to install the tool:

sudo apt install acl

Otherwise, follow your OS documentation, because you may need to change how your partition is mounted (Ubuntu documentation here).

And there we are:

sudo setfacl  -R -m u:"www-data":rwX -m u:`whoami`:rwX app/cache app/logs
sudo setfacl -dR -m u:"www-data":rwX -m u:`whoami`:rwX app/cache app/logs

I never had any problems with this method, satisfied or your money back.

Solution 2

No matter who's the owner of the files, 666 permissions and 777 would be enough: the last digit makes sure that every user on the system has access. While this is the easiest way to do it, it is definitely not the safest for that exact reason.

A better way to do it

The first thing you need to understand is how Unix permissions work. In the interest of understanding the answer I gave at this link, please note that permissions can be translated to numbers:

  • 0: ---
  • 1: --x
  • 2: -w-
  • 3: -wx
  • 4: r--
  • 5: r-x
  • 6: rw-
  • 7: rwx

A chmod 666 is then equivalent to changing permissions to rw-rw-rw.

Next you have to figure out which is the user that is executing the PHP script. Normally that would be the user running your web server. Here's an example of how to do this (you can replace Apache with the name of your web server).

Once you know which is the user executing the scripts, and which's the owner of the files you mention, it is up to you to set appropriate permissions. Keep in mind that giving write access (even read) to every user on your system can be potentially disastrous.

Share:
120,782

Related videos on Youtube

oshirowanen
Author by

oshirowanen

Updated on September 18, 2022

Comments

  • oshirowanen
    oshirowanen over 1 year

    UPDATED FOR FURTHER CLARITY:

    According to http://expressionengine.com/user_guide/installation/installation.html, it says:

    For most Unix hosts the following is typical, but you may check with your host to see if more restrictive permissions can be used to allow PHP to write to files (666) and folders (777). On Windows servers the following will not apply, but you will need to ensure that the files and folders are writable by ExpressionEngine. You may need to contact your host for this.

    Not sure what this means. I can change the specific files and folders to 666 and 777 respectively where I am the chown'er, but the above sounds like I need to allow PHP to do this too?

    ORIGINAL QUESTION:

    I need to ensure that PHP can write to specific files (666) and folders (777).

    How do I do this?

    • Karlson
      Karlson about 12 years
      I am not sure what problem you are trying to solve? If you can access the directory where file is located and have execute permission in it you can write to files and directories with those permissions.
    • oshirowanen
      oshirowanen about 12 years
      Added further details above.
    • Karlson
      Karlson about 12 years
      For most Unix hosts the following is typical, but you may check with your host to see if more restrictive permissions can be used to allow PHP to write to files (666) and folders (777) -- Is there a coma missing? otherwise this phrase doesn't make any sense. Unless higher level directory is restricted you have no issue writing to world writable files or directories.
    • oshirowanen
      oshirowanen about 12 years
      I just did a copy and paste from the documentation. Plus, it's the reason why I posted the question as I don't understand what that quote means...
    • Karlson
      Karlson about 12 years
      You're not the only one. Best guess is that author wanted to talk about files and directories with permissions other then 666 and 777. Again best guess but a coma after can be used would have made it clearer
    • jsbillings
      jsbillings about 12 years
      If you see documentation suggesting that you use 666 or 777 in relation to web files, you should probably ignore it unless there is a good reason explained. It's usually something written by someone who couldn't figure out how to set up the right permissions, and gave up and gave everyone read or write access to the files.
    • Snitse
      Snitse about 12 years
      Is PHP being executed by apache? Do you have root access to the machine?
  • Amar Pratap
    Amar Pratap almost 8 years
    +1 for 'ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1 '
  • tony gil
    tony gil over 3 years
    i just added a added bounty, will award it to tis answer in 24 hours. UPVOTED, excellent answer, clearest on this subject that i have read to date. deserves bounty!
  • Morgan Touverey Quilling
    Morgan Touverey Quilling over 3 years
    Thanks a lot @tonygil!
  • Boyan Alexiev
    Boyan Alexiev about 3 years
    It's good to note that the numerical representation of the rights comes from the binary numeral system where you use only 0 and 1. Each bit has a corresponding value in decimal, which can be calculated easily starting from the rightmost bit, by using "2 to the power of" 0, 1, 2 and so on going to the left. So, a binary number 101 will be decimal 5. So, we see that eXecute is the rightmost bit and hence has a value of 1. The Write is the second bit with a value of 2 and Read has a value of 4. When you combine Read and Write you get 4+2+0 = 6. Then user, group and for others are combined.