9

I am in the process of migrating a couple of Wordpress blogs over to AWS and have run into an issue with file permissions that has successfully foiled me for the last couple of hours.

The simplest possible fopen call always fails with "failed to open stream: Permission denied":

<?php $handle = fopen('test.txt', 'w') or die('Can\'t open file'); ?>

I have tried/checked the following

  • The directory I'm writing to has the correct file permissions (755) and the correct ownership. This is true all the way up the path to /home.
  • I am writing the correct directory as confirmed by getcwd()
  • The test PHP script hash the same ownership as the path I am trying to write to and correct permission (644).
  • I'm running mod_suexec to ensure the script is executed with the same user and group as the path I am writing to. The functions getmyuid() and getmygid() return the correct user and group IDs (Edit: This is wrong see below).
  • PHP safe mode is disabled in php.ini.
  • fopen is not a disallowed PHP function.
  • The use of open_basedir is disabled.

Is there anything I have missed that might be causing this? I suspect I've been staring at this for so long I'm missing something obvious.

Update: After applying womble's suggestions I am starting to think this issue is more nefarious than just bad permissions or a PHP misconfiguration. I did manage to get the above code to write out a file, however even though the PHP script executed with the correct user and group the resulting files ownership and group were set to that of apache. If I execute the same test script from the command line the emitted file has the correct permissions. This leads me to believe it is an issue with my use of mod_suexec.

Edit: My use of getmyuid() and getmygid() are incorrect as they only return the user and group of the script file not the permissions it is running with. A more correct approach is to use comething like this:

<?php echo exec('ps -up '.getmypid()); ?>
Kevin Loney
  • 258
  • 1
  • 4
  • 8

4 Answers4

5

Good question -- shows you've done your homework.

I can't think of anything "obvious" that you've failed to check, so I can only give you some more advanced debugging advice.

  • Fire up strace on the PHP process, and see exactly what it's doing under the hood.
  • Write a bit of code that does an fopen(..., 'r') to triple-check that your directory tree permissions are, in fact, OK.
  • su to the user in question and try doing some stuff on the command line. If that works, then you know your script isn't running with the permissions you think it is.
  • Check that there are no extended ACLs on the file, directory, or leading path components (getfacl is the tool to use). It's uncommon, but every once in a while they'll leap up and rip your face off. If you do have ACLs, use setfacl -x to get rid of them once you've verified they're unnecessary.
womble
  • 95,029
  • 29
  • 173
  • 228
  • The file has no extended ACLs, fopen(..., 'r') works correctly, and it successfully writes the files when I run php on the command line as when su'd in as the user. I did manage to get it to write out a file when executed by apache and have updated the question with my results. – Kevin Loney Jul 23 '11 at 01:27
  • If the file was created owned by `apache`, then the script is running as `apache`, whatever your other testing suggests to the contrary. I'd say your `suexec` config is pooched. You should ask about that on Server Fault. – womble Jul 23 '11 at 01:36
2

Check what is the home folder of apache (normally it is /var/www) and put the files under this folder, finally then give necessary permissions. Change the php temp upload folder to this. This is working for me.

Bart De Vos
  • 17,761
  • 6
  • 62
  • 81
user101119
  • 21
  • 1
1

try /usr/sbin/apachectl -t -D DUMP_MODULES

check that all modules enabled

If you get

Warning: SuexecUserGroup directive requires SUEXEC wrapper.

Resolution

Such warning is usually caused by invalid permissions on suexec wrapper, it should be:

# ls -la /usr/sbin/suexec
-rwsr-xr-x 1 root root 12064 2008-04-17 01:15 /usr/sbin/suexec

If the permissions or ownership are differ from the example above, use the following commands to correct them:

# chown root:root  /usr/sbin/suexec
# chmod 4755 /usr/sbin/suexec

after this fix everything was ok.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
Vitalijus
  • 19
  • 1
-1

2 things.

  1. You need to escape the apostrophe in your die statement.
  2. 5 is r-x, 6 is rw-. I would set your permissions at 0766 for -rwxrw-rw-
Jason Berg
  • 18,954
  • 6
  • 38
  • 55
Daniel Baker
  • 179
  • 2
  • The docs for Wordpress indicate that 755 is the correct directory file permissions. This shouldn't matter anyway either as the php script is executing with the same user and group as the directory being written to. – Kevin Loney Jul 22 '11 at 18:04
  • Wordpress cares less about the permissions of it's files. It's Apache that will be serving the pages provided the filesystem permits it. Same goes with writing to a file. Worpress applies to Apache to write. If Apache is configured to allow it, Apache applies to the Filesystem for the write, if the file doesn't have the write permission set then the request is rejected. set 0777 for your write folder, as well as the file. See what happens. – Daniel Baker Jul 22 '11 at 19:04
  • One extra thing. The file performing the write does not need write permissions. Only the file and directory being written to. http://www.linux.com/learn/tutorials/309527-understanding-linux-file-permissions – Daniel Baker Jul 22 '11 at 19:12
  • fopen still fails with permission denied after setting 0777 on the write folder and file – Kevin Loney Jul 22 '11 at 20:15
  • 1
    0766? Really? I'd love to know a legitimate reason for ever using that permission set. – womble Jul 22 '11 at 23:29
  • +x on a directory is traversal, not execute. If a directory is readable, normally traversal should be set also. – Falcon Momot Aug 21 '12 at 04:44