In my first PHP script in many years, I'm trying to log an error:
error_log("my error message", 3, $error_log);
I'm getting an error in the general Apache error log:
PHP Warning: error_log(/var/log/apache2/my_php_errors.log): failed to open stream: Permission denied in /var/www/html/blahblah/my_script.php on line 88
This is what I've checked and tried:
Created $error_log with the same ownership (root.adm) and permissions (640) as the Apache error log.
Changed the owner to www-data, which is the user PHP is running as.
log_errors is On.
open_basedir is not set.
Using PHP 5.5.x, so safe mode does not exist.
What am I missing?
Edit: It's able to write to the general Apache error log. The mystery is why it can't write to another file in the same directory with the same ownership and permissions.
Edit 2: Another developer told me that this works on his WAMP, so it's something specific to my LAMP stack or config.
I had the same problem.
https://serverfault.com/questions/831444/php-error-log-per-vhost/831666#831666
touch /path/to/php_error.log
chown www-data:www-data php_error.log
chmod 755 php_error.log
thanks for leading me to the answer!
TL;DR: check that all the ancestor directories allow reads/lists by the web server.
On my system, my equivalent of /var/log/apache2/my_php_errors.log was giving this same error. I eventually did an ls -ld at every level of the path (/, /var/, /var/log/, /var/log/apache2/, /var/log/apache2/my_php_errors.log).
Four of those had permissions that made them readable by the web server. One of them, /var/log/apache2/ did not. When I moved my file out of the apache2 directory, everything started working. E.g. /var/log/php/ and set appropriate permissions/ownership (e.g. 750 by www-data.adm) on the new directory.
prompt> ls -ld /var/log/php/
drwxr-x--- 2 www-data adm 4096 Nov 1 13:31 /var/log/php/
You could also change the permissions on /var/log/apache2/, but that seems like a security/privacy issue. It's safer to make a new directory and leave the existing structure as is.
The reason why the permissions have to change is that it is no longer using some version of syslog to publish to the log files. The syslog variants run as root and accept messages from non-root. But in my case, I was specifying the file from the web server, which made the permissions wrong.
There is a fix that uses syslog so that it could keep the same ownership. I did not try to make that work, as this is for a test server.
This may not have been the problem that you were having, but I'm pretty sure that I was using the default permissions for /var/log/apache2/. So it's quite possible that it was the problem. And even if it wasn't, this is one of the places I was searching for troubleshooting advice. So next time something like this happens to me, I'll have a reminder of what to check.
Related
I'm a bit confused here in Symfony functionality terms. I have a website which is supposed to write sessions in /var/lib/php/sessions/. I'm confused right there, because in /var/www/html/myproject/ everything is recursively property of www-data:www-data (yes, I'm using Apache). However the owner of /var/lib/php/sessions/ is root, so when Apache tries to write there, I get a 500 server error regarding writing permissions in that directory.
I have divided opinions here. Some people advice me to modify config.yml to manage sessions inside the project directory, while other people say that is a really bad practice. But, how do I get everything targeting /var/lib/php/sessions/ without that file permission error?
Here's what I get via Apache URL:
Oops! An Error Occurred
The server returned a "500 Internal Server Error".
Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.
Here's what I get via php development webserver:
Warning: SessionHandler::read(): open(/var/lib/php/sessions/sess_u3eg1842nlpkbm0rvddrq37dc2, O_RDWR) failed: Permission denied (13)
500 Internal Server Error - ContextErrorException
I really hope you can help me.
In order to create a file the user must have write and execute permission on the directory.
mkdir /tmp/foo
chmod 300 /tmp/foo
touch /tmp/foo/bar
test -e /tmp/foo/bar
In your case setting the 'other' permissions to 3 would allow www-data to write to it. chmod o+wx /var/lib/php/sessions/
In order to remove a file the user must also have write and execute permission on the directory.
In order to list the file names in a directory the user must have read permission on the directory. Note that if you know the filename it's not required to have permissions for listing the directory.
In order to list the properties of a file the user must have execute permission on the directory.
On my computer the permission for /var/lib/php/sessions is drwx-wx-wt. The t indicates execute & sticky bit. Sticky bit for directories means only the owner can delete it.
See Unix File and Directory Permissions and Modes by Wayne Pollock for more info.
I have seen many questions and answers on this topic but none seem to help my situation. My PHP code is successfully creating a new logfile, but then cannot access that file to append further info, close it, etc.
I am migrating an application from local XAMPP onto LAMP: hence problem only showing up now due to Windows/XAMPP giving no permission troubles.
I started with a default Bitnami LAMP stack, and then manually setup relevant directory permissions on server:
- my sftp user has rwx on htdocs and assorted out-of-web-root directories
- apache is running as 'daemon' so I have given read & execute permissions to relevant directories for 'daemon' as group
- in most directories I have disallowed write permissions for 'daemon'
- however for my (application generated, internal) logs I have a 'logfiles' directory which has rwx for both my user and the 'daemon' group
- 'other' is -rwx for all
When I run my application it falls over pretty much immediately. The error logs showing fopen failed to open stream: permission denied. However, the permissions indicate that it should have access.
When I check the file involved it has following permissions:
-rw-r--r-- 1 daemon daemon 962 Oct 3 10:14 20151003logfile03-10-33530.txt
This tells me that the file was created by Apache (i.e. by my PHP script) and that it has read and write permissions, from when I fopen() with "w"
EDIT: adding directory info:
Folder level permissions give my ftps user and daemon (group) full rwx access:
drwxrwx--- 2 ftpuser daemon 4096 Oct 3 10:30 logfiles
BUT it can't then fopen with "a"
I am assuming that this IS a file permission problem because:
a) it works fine on XAMPP
b) it states permission error in the error log
However, I can't see why it should be a problem, given directly-specified OS-level permissions ... maybe Apache requires an .htaccess 'allow' on this directory also?
Any ideas?
Clarification re why I don't think CHMOD is the answer (sorry #RedAcid):
CHMOD 777 etc is simply a way to set the underlying permissions I already have. Each digit represents 3 binary chars, so 7 is 111 (i.e. read, write and execute). As you can see above, I have read/write/execute for PHP/Apache on folder, together with read/write for file. What I've read suggests that you need execute at directory level, but not at file level because its not trying to execute the file.
So what am I missing here? Why else might it be denying permission?
use chmod 666 for the file and proper user group permissions. folder where files are located must be writable with chmod 777
OK - I found out the problem was higher level parent directory not having read/execute permissions. Now working! (AT LAST!)
For more detail see this previous question:
PHP fopen() fails on files even with wide-open permissions
I see that similar questions have been answered on Stack Overflow, but the solutions haven't fixed my particular problem, so I have to ask...
I have an app that needs to make directories and modify files outside the site directory. This works find on the production server.
After spinning up a test server with the exact same version of Ubuntu and PHP, I'm getting errors on the staging server when it tries to open files or create directories.
Here are the errors:
mkdir() [http://php.net/function.mkdir]: Permission denied
fopen(/root/Dropbox/Backend/Booth-01/settings.sh) [http://php.net/function.fopen]: failed to open stream: Permission denied
Things I have tried:
checking the username running the application (it's www-data)
changing the owner of the external directory recursively to www-data
changing permissions on the directory to 777 (I know, this is a bad idea, but I was just trying it to see if that would help until I figured out what the issue was and will change the permissions to something more restrictive once I get it working)
checking the umask value. It was set to 0002, which shouldn't give me problems. Just for kicks, I tried changing it to 0000 and it didn't help.
checking to make sure PHP's safe mode wasn't enabled.
checking to make sure that nothing was specified in open_basedir. In any case, if that was the issue, it would throw a different error message.
I can't think of what to try next and I'm hoping that someone else is seeing something that I'm not.
Ubuntu 12.04.5 x64
PHP 5.3.10
It's not only the folder itself you have to have permissions on. You should also check the parent folders. I think, if you check this, this will fix your problem.
If this is an external drive (see if it shows up in mount) then you may have to remount it. An auto-mounted external drive can thwart permissions
sudo umount <moint-point>
sudo mount /dev/<device> <new-moint-point>
I currently have a php script that is running when a browser browser browses to the webpage. What I'm trying to do is write a text file when the script runs that stores a variable. The owner of the folder is apache, but everyone has read write, strictly for testing purposes. (I thought it might be a permissions issue) SELINUX is enabled on the server, and when I run the script from console it creates the text file just fine, and in the right directory.
file_put_contents("My working file location", $myString);
I'm using this line to try to write and create the text file, I know that my file location works becaus I can run it and create it in offline mode, I.E. running it through console. The problem is that the variable I'm trying to write is populated through HTTP Post, and when I run the script through the browser, or when apache runs the script, it does not write or create the file. What do I need to do to allow access to write/change syntax wise to get this script to write this text file?
Your problem is likely due to apache not having permissions to write to the file location you specified. Go to that directory and check the permissions and group ownership with the ls command:
cd "My working file location"
ls -l .
There are three columns in the output that show the permissions, owner, and group for the directory. Most likely they are owned by root and don't have permissions for apache to write to the directory.
If this is the case, then you will see an error appear in your apache log when it tries to create the file. Try tailing your logs while running the script in your browser:
tail -f /var/log/apache2/error.log
I had the same trouble recently and stumbled upon this question. Unfortunately choppyfireballs the OP said in a comment he found his own solution and just accepted an answer that wasn't helping any of us... Then after a search and a success to make file_put_contents work again I decided to share my solution.
The permissions of my files and directories were ok to accept any writing (make sure your directories are chmod 757 this will give the root and others the grant to write files in the location). If it still doesn't work like it didn't for me, that's because your system is probably SELinux (Security Enhanced Linux) system.
If you want to make sure write setenforce 0 this will turn selinux to permissive mode, run your script again, if it works then it means the problem is well described.
In that case turn selinux on back setenforce 1 and try ls -Zl in the directory where the directory of your project is. this will give you a line like
drwx---r-x. 9 root root system_u:object_r:httpd_sys_content_t:s0 4096 Dec 8 00:25 project
or something different but httpd_sys_content_t if you used chcon to transfer the context from one directory to this one. but if you don't have httpd_sys_content_t it's ok because we need to change the context of that directory anyways.
first you need to accept any public_content_rw_t contexts to write file. Type
setsebool -P httpd_anon_write on
This will set (P)ermanently SELinux boolean httpd_anon_write to true and any context dubbed as public_content_rw_t will have the rights to write any files in their own location.
Now you have to say SELinux that your project directory is public_content_rw_t or you'll still not be able to write files. Type :
semanage fcontext --add --type public_content_rw_t "/project(/.*)?"
and restorecon -RvF /project to tell selinux to apply the above specifications.
Now your directory is public_content_rw_t and you should be able to write files.
I ran into this problem too. In my case, I found that the ownership of the directory was wrong. For a typical Apache installation the directory should be owned by www-data:www-data, not root:root.
Something else to try, for people with a similar question. You might just be making a simple mistake that doesn't require you to mess around with the file permissions—and if you're making this mistake, fixing the file permissions might not help.
Be sure you're using a local, relative file path in file_put_contents().
For example, use:
file_put_contents('short_local_path/my_working_file.txt', $myString);
Not:
file_put_contents('http://example.com/remote_path/my_working_file.txt', $myString);
And not:
file_put_contents('/whole/root/file/path/to/my_working_file.txt', $myString);
Have you tried chmodding the directory to 777?
Try this:
if(file_put_contents('file.txt', 'text')){
die('yes');
} else {
die('no');
}
Might of misspelled something. ^
I recently moved my website to a new host and now am experiencing some broken code..
I have an uploading script that is now returning this:
move_uploaded_file() failed to open
stream: Permission denied in *..
I've set the upload directory to 777 which worked fine, but my script is needed to have top level permissions..
(As the script itself sets permission to directories, does lots of copying etc)
Is there a way in apache I can set the PHP script to the owner of all the folders on my server?
Thanks
Also
When looking in phpInfo()
Under
apache2handler
User/Group nobody(99)/99
Is this related?
I wouldn't go that route, just give it permissions to the defined upload_tmp_dir, or define upload_tmp_dir to be a directory you have access to. If it is that directory you have problems with. If the target is the problem, and you've 777'ed it, something fishy is going on.
Do you have ssh access to your new host? The reason I ask is that it's probably not best to use the username/group as nobody, as most other services would use this too. I would change it to something like apache
You can then update httpd.conf, adding in these two lines (reloading the config after):
User apache
Group apache
Then, run chown apache:apache -R dir_name to make apache own it.
well,
When you are trying to set the permission like "0777", you must be running on same authority.
What I mean is.
For example, your script tells to change a folder/file permission to 0777, but the folder or file already has a permission and that is '0755' so you are not authorised to make that change. as the user have only 5 authority.
Either, you need to login to FTP and change the folder permission to 0777 and then you have full control over it or you have to stick with using 0755 or similar.