I have a simple script which copies a file from one SMB mount to another. The source file system is the same, but the web server is different. I'm using PHP to process the file by copying it to a temp directory, then performing additional tasks on it. This setup was working at one point in time but it seems that it's no longer working correctly. Can someone point me in the right direction?
fstab mounts:
//192.168.0.x/share /media/folder smbfs username=user,password=mypass
//192.168.0.x/share2 /media/folder2 smbfs username=user,password=mypass
php code:
copy('/media/folder/filename.txt','/media/folder2/temp/filename.txt');
Error:
Warning: copy(/media/folder2/temp/filename.txt): failed to open stream: Permission denied in /www/myphp.php on line xx
Folder permissions (not the mount, but the source folder on the fileserver):
/media/folder = 777
/media/folder2/temp = 777
system("cp /media/folder/filename.txt /media/folder2/temp/filename.txt");
Might work for you.
sounds like a question that is specific to permissions and the OS and not PHP .. what webserver? what is the server running as? nobody:nobody? can nobody:nobody or www-root:www-root read/write data into the directories you are trying to access?
sudo su - nobody
probably wont work as it will most likely have a /bin/false shell
nobody may not be the right account .. ps auxw | grep apache | awk {'print $1'} and see which user it is running as ... then try changing over to that account with sudo
Before PHP can have access to write the files, you need to ensure the user which the webserver is running as ... has access to read/write to the directory you are trying your copy on.
I changed the command to:
copy('/media/folder/filename.txt','/tmp/filename.txt');
Apparently it's more difficult to process files on an SMB share than I thought. The file should be removed when the computer's rebooted, or possibly at regular intervals, depending on the system setup.
Related
I know this is a common issue but I haven't been able to single out the problem for my specific use case, so bear with me.
I have a simple PHP script send_id which simply sends an ID number and saves it to a TXT file on my RHEL server running Apache 2.4.6 with PHP 5.4.
The error message: Warning: file_put_contents(/var/www/html/id.txt): failed to open stream: Permission denied in /var/www/html/send_id.php on line 6
'1' written to server
The PHP script itself:
<?php
$id=$_GET['id'];
$stringData = "$id";
$file = file_put_contents('/var/www/html/id.txt', $stringData.PHP_EOL , FILE_APPEND |LOCK_EX);
echo "'$stringData' written to server";
?>
chmodding to 777 didn't do anything. Additionally, I checked to see ownership rights and noticed that the id.txt file is owned by the root user at both user/group level, and PHP is being run at root level.
Anyone have any suggestions? If its any help, this seems to have happened after a yum update
I resolved this issue by simply running chcon -Rt httpd_sys_content_rw_t on the directory where my troubled PHP script lived in.
The chcon command changes the SELinux context for files. However, changes made with the chcon command are not persistent across file-system relabels, or the execution of the restorecon command.
-Rt are to change the type of the directory and its contents, httpd_sys_content_rw_t is to give apache write access
source: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-working_with_selinux-selinux_contexts_labeling_files
Additional note
ls -alZ *
The -Z switch will work with most utilities to show SELinux security contexts
Try changing the owner of the folder and the file to (chown) to "www-data" or to "www-data:www-data" and see if it changes anything...
Use a relative file path from, Apache's "DOCUMENT ROOT" to reference files in PHP. It's Apache's permissions that matter, and for security reasons it is coded to inhibit access to files outside of DOCUMENT_ROOT.. (yes even though your path leads within it, Apache is blocked as soon as it sees the path starts with "/VAR" ..
Assuming this PHP script is in the same directory as id.txt file , just use
$file = file_put_contents('./id.txt', $str...
Or if the txt file was in a sub-directory
file_put_contents('./sub-dir/id.txt', $str...
Not only is it secure, it's a lot shorter to type too.
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'm trying to use this Dagon Design PHP form to help a local non-profit publication enable their readers to submit photos. I've got the "mailer" part working -- the notifications work fine -- but the "saving a file to a folder" part isn't functioning.
On the form page, the author says "the directory must have write permissions," but I'm not sure "who" is writing to that folder -- is this PHP script considered "Owner" when it saves something on my site? Or do I need to allow save permissions for Owner, Group and Others?
I'm not sure why the script isn't saving the photos, but this seems like a good place to start. I've tried looking around on Stack for answers, but most questions seem to have to do with folder creation/permissions.
The page I'm clumsily trying to build is here, if that helps.
As Jon has said already, you don't want to allow write access to everyone.
It's also possible (depending on the hosting) that something like suEXEC is being employed - which will cause your PHP script to run as a user other than the webserver's (as reported by Dunhamzzz).
Probably your best approach, in my opinion, is a script calling whoami:
passthru('whoami');
Or alternatively you could try:
var_dump(posix_getpwuid(posix_geteuid()));
Bear in mind, this does give system information away to the world - so delete the script once you've used it!
Then, as you've correctly asserted in your question, it'll likely be the file permissions.
If you do have CLI access, you can update the permissions safely as so (first command gets the group)
id -n -g <username>
chmod 770 <directory>
chown <username>:<group> <directory>
(You may have to pre-pend "sudo" to the "chown" command above, or find other means to run it as "root"..., reply back if you get stuck.)
If you've not got access to run command-line, you'll presumably be doing this via a (S)FTP client or the alike. I'm afraid the options get a little to broad at that point, you'll have to figure it out (or reply back with the client you're using!)
As always, YMMV.
Finally, bear in mind if this is your own code, people will at some point try uploading PHP scripts (or worse). If that directory is accessible via a public URL ... you're opening the hugest of security holes! (.htaccess, or non-document root locations are your friend.)
If you are not sure how is your server configured (and this would influence who's the final file owner) then add write permission to anyone (chmod a+w folder), upload one file and ls -l to see the owner. Then you can adjust permissions to allow write access to certain users only
The PHP script that saves the files is running with the privileges of some user account on the server; the specific account depends on your OS and the web server configuration. On Linux and when PHP is running as an Apache module this user is the same user that Apache runs as.
Solving your problem reduces to determining which user account we are talking about and then ensuring that this user has permission to write to the save directory (either as owner or as a member of the group; giving write access to everyone is not the best idea).
You'll need to set the permissions of the directory to that of the webserver (probably Apache, nginx or similiar), as that's what is executing the PHP.
You can quickly find out the apache user with ps aux | grep apache, then you want to set the permssions of the upload directory to that user, something like this:
chown -R www-data:www-data images/uploads
I am currently over ssh on a remote CentOS 5.6 system which runs an Apache webserver. I need to use the poppler pdftohtml binary which, unfortunately, is not currently installed on that machine. So I downloaded the poppler package and built it under my user folder. Since I I am not the system admin, I didn't do
make install
and I have all my compiled files under
/users/myfolder/poppler-0.18.2/
The file that I need to execute through php shell_exec() is
/users/myfolder/poppler-0.18.2/utils/pdftohtml
If I execute it through my ssh bash, I get the correct output. If I, instead, put this line on a php script:
echo shell_exec("/users/myfolder/poppler-0.18.2/utils/pdftohtml");
I get the following output:
sh: /users/myfolder/poppler-0.18.2/utils/pdftohtml: Permission denied
I tried setting to 777 the file permissions, which currently are -rwxrwxrwx. I also noticed that using shell_exec("whoami"); results in "apache". Shouldn't apache be able to execute the script if the file permissions are -rwxrwxrwx?
I also know that installing poppler through make install would solve the problem but since this is for testing purpose, I would like to avoid "contaminating" the system outside my personal folder until the testing is complete.
Thanks to anyone who will help!
Just because a file is executable for a user does not mean that user is actually able to execute the file. The user needs to also be able to 'get to' the file: The user needs execution permission for all 'parent directories', in your case for /users, myfolder, poppler-0.18.2 and utils.
Assuming /users is the same basic thing as /home, everybody should have +x on that. From there, you can set it: simply do chmod o+x /users/myfolder /users/myfolder/poppler-0.18.2 /users/myfolder/poppler-0.18.2/utils
(Note: This will make it possible for everybody to execute this binary, not just Apache.)
If the apache user and you share a group, it would be better to use chown the poppler directory and everything in to be owned by that group, and set g+x instead of o+x.
I'm running php script updreading.php locally on my laptop (with Mac OS X 10.6.7).
Here's the contents of updreading.php
<?php
$outFile = "examples-output.txt";
$out = fopen($outFile, 'w') or die("can't open write file");
?>
When I run it, I get "can't open write file" error message. I think it should have something to do with permissions. I've made myself (arman) an owner of /Library/WebServer/Documents/ with Read&Write permissions and 'applied settings to enclosed items'. My script and file I'm writing to (examples-output.txt) is located in /Library/WebServer/Documents/wabun/. Here are the permissions for files in /Library/WebServer/Documents/wabun/:
-rw-r--r--# 1 arman admin 0 May 1 01:03 examples-output.txt
-rw-r--r--# 1 arman staff 1657 May 1 01:04 updreading.php
I was trying to resolve the issue for the last 4 hours trying different permissions without luck. Any ideas how to resolve this issue, guys? Thanks!
I was having this exact same problem. I had to make sure the permissions were correct for all of the parent folders as well. For instance, if (in OSX) trying to write to the directory
~/foo/bar/baz, I solved it with the command chmod -R 777 ~/foo.
I bet the issue is that your webserver or PHP instance is not running under the same user (arman), you can check this using the get_current_user() function. You can either configure apache to run with your privileges (ask in ServerFault) or give the folder more generous permissions, like 0777.
Another thing, are you sure $outFile maps to an absolute path? Try doing:
var_dump(is_file($outfile));
you need to make apache (assuming apache is server you are using) the owner or put in group (and give group write access) or give write access to all or etc.. IOW apache is the one actually executing the script, not you.