Write to tmp folder - php

EDIT 1
This question involves the user of the MANGOPAY API. My problem is that I cannot get the API to write to the tmp folder.
I have succeeded in getting the API to write to http://fakedomain.com/apifolder/blank.txt and getting the appropriate output.
I then ran the script http://fake.com/apifolder/demos/iswrite.php on http://fakedomain.com/apifolder/blank.txt to have minimal working code I could test on the tmp folder. Here is the code in the script:
<?php
$filename = 'blank.txt';
echo "<br>";
file_exists($filename);
echo "<br>";
if (file_exists($filename)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
echo "<br>";
if (is_writable($filename)) {
echo 'The file is writable';
} else {
echo 'The file is not writable';
}
?>
It gives me the output
The file blank.txt exists
The file is writable
so all good there. I created the following file with the following permissions using Filezilla:
In the script http://fake.com/apifolder/demos/iswrite.php I have changed the filename variable to $filename = 'http://fake.com/tmp/creative/blank.txt';. It gives me the following output:
The file http://fake.com/tmp/creative/blank.txt does not exist
The file is not writable
Also, allow_url_fopen is on.
I don't fully understand URL structures, so maybe the problem lies there? The tmp folder I am trying to access is on the same level as my public_html folder. Maybe I am writing my URLs wrong?
Put in another way, does the tmp folder have to be outside the public_html folder? Would there be any purpose to this? Or can I have create my own tmp folder within public_html where it is already working?
ORIGINAL QUESTION
The original question was poorly written. Please see EDIT 1
I am playing with the sandbox of an API (MangoPay). I have included my ClientId and ClientPassword which seems to work.
The API also says...
You also need to set a folder path in $api->Config->TemporaryFolder
that SDK needs to store temporary files. This path should be outside
your www folder. It could be /tmp/ or /var/tmp/ or any other location
that PHP can write to.
I have created one at:
ftp://fakedomain#fakedomain/tmp/fakefoldername
I am running the php script from my desktop using Terminal. The output it is giving me is
Cannot create or write to file
ftp://fakedomain#fakedomain/tmp/fakefoldername
even though I have set permissions to 777.
Any idea of why I am getting this error?

I am guessing the library in question is this one, and the error you are getting is this exception:
if (!is_writable($this->GetPathToTemporaryFolder()))
throw new \MangoPay\Libraries\Exception('Cannot create or write to file ' . $this->GetPathToTemporaryFolder());
So basically we seem to be debugging a call to is_writable().
make sure allow_url_fopen is on
if applicable, make sure the URL includes the FTP password
make sure the folder exists and the FTP account has write permissions (777 should suffice...)

Generally speaking a temp dir is supposed to be located on the same machine as your code. Using FTP is less than ideal. Are you not able to use a local directory?
You'll notice in the MangoPay documentation it shows a local dir:
https://github.com/Mangopay/mangopay2-php-sdk
$api->Config->TemporaryFolder = '/some/path/';
You should probably stick to that, instead of using a remote server via FTP.

An out-of-the-box Linux machine running Ubuntu 14.04 has the following user and permission settings
drwxrwxrwt 13 root root 4096 nov 9 00:56 tmp//
And the dummy directory
drwxrwxr-x 2 eric eric 4,0K nov 9 00:49 fakefoldername/
In case of switching to 777 permission set (as you said, you have already done this), that would be
drwxrwxrwx 2 eric eric 4,0K nov 9 00:49 fakefoldername/
The point to notice here is that if you used chmod 777 fakefoldername it changes the permission set only to the directory without touching any of the files/directories in fakefoldername (use chmod -R 777 fakefoldername). Another point to remember is that directories leading to the fakefoldername also need to have sufficient perms. For this particular case, check if /tmp folder has them, fix if necessary
sudo chmod 1777 tmp/
Also, as stated above, I would try to make another directory in /var directory and see how things are going then (an nice answer why to or not to choose /var/tmp over /tmp here).
For others: the SDK that is used is probably https://github.com/Mangopay/mangopay2-php-sdk
There might be some hints in the somewhat similar answers below:
http://forum.odin.com/threads/error-message-cant-create-write-to-file-tmp-after-overflow-tmp.296376/
https://unix.stackexchange.com/questions/39466/vsftpd-553-could-not-create-file-permissions

Most likely, your apache dont have permissions to write that folder, you have to be sure that you are creating that directory with same user (in your case, apache) and also chmod.

Related

Using PHP to move files between cPanel accounts on the same server

We recently upgraded our server to cPanel 78 and migrated from EA3 to EA4. Our server only has two sites on it, and prior to the upgrade we could use PHP scripts to copy files between the two sites using PHP's file_exists() and copy() functions.
We could use the file_exists() function to grab files from site1 and migrate them to site2 using code similar to this:
$current_path = '/home/site1/public_html/uploads';
$new_path = '/home/site2/public_html/uploads';
if(file_exists($current_path.'/v2n62l6v.jpg')) {
echo 'File exists: true' . "\n\n";
copy($current_path.'/v2n62l6v.jpg', $new_path.'/2020/03/30/v2n62l6v.jpg');
} else {
echo 'File exists: false' . "\n\n";
}
This code also creates new directories and sets the permissions to 0755.
After the upgrade, when we attempt to execute the script, we are greeted with this error:
File exists: true
Warning: copy(/home/site2/public_html/uploads/2020/03/30/v2n62l6v.jpg): failed to open stream: Permission denied in /home/site2/public_html/move.php on line 15
We are able to move the files if we set the permissions to the folders to 0777, but I would prefer to not have to change all of the folder permissions (there are 10s of thousands).
Any ideas on where to start or what settings may have changed during the upgrade to either EA or cPanel/WHM?
Site is using:
PHP 5.5 (ea-php55)
DSO PHP Handler
CENTOS 6.10
cPanel v78.0.47
I am happy to provide any other information to help trouble shoot this issue.
Thanks so much for any/all help.
As you said that it is CentOS so the following should work
<?php
$current_path = '/home/site1/public_html/uploads';
$new_path = '/home/site2/public_html/uploads';
//Below command will copy paste all folders recursively
shell_exec("cp -r $current_path $new_path");
echo "All Done";
?>
If the above one doesn't works for some reasons then try going to the SSH terminal directly and run that shell command with your paths.
As you mentioned in comments that you want to further process the files that could be done on site2 itself once all files are there you could scandir/is_dir to scan and process files. But that is different topic.
If you really need to do this you have to make sure php user owns both sites files - apparently this is not your case.
Alternatively you can use root user to copy files preserving ownership and permission or changing their owner and permission at the destination accordingly.
One other option is to umask user privileges before your operation; Is strongly recommended to revert umask value after operation is completed:
https://www.php.net/manual/en/function.umask.php
Ex:
$old = umask(0);
//your operation here
umask($old);

chmod the folder to make it writable for the server in php

i am trying to upload a file on server via PHP form. Data is all working find ad getting image name in DB perfectly but issue is that i am not getting image on server.
I googled and found that DIR is not writable. I checked with below code:
$image_folder = $destination_folder . $new_file_name;
if ( ! is_writable(dirname($image_folder))) {
echo dirname($newFileName) . ' must writable!!!';
}
and then to change the permission, i tried using chmod('$destination_folder',0777) but all of a sudden a thought striked to mind that should i give write permissions to all on server.
Ideally answer is no but then how can i handle it..??
you can give permissions 755,
7 5 5
user group world
r+w+x r+x r+x
4+2+1 4+0+1 4+0+1 = 755
You have to know who is the owner. Default makes it sense who creates the folder.
You can use 755 if php creates the folder (php user is owner: the first 7 = full rights for owner) (recommend)
If e.g. ftp user is owner, upload via php user with 755 permissions for dir is not enough: php user has no write permissions.
probably not the answer you're looking for, but if you find that PHP can't write files to anywhere on the filesystem, and you can't chmod a directory for uploads, you could always store the images in the database

Upload files to the folder outside root folder in Linux server?

In my project, I have to upload some video files to a folder which lies outside the root folder. I am using simple php function move_uploaded_file to upload the file. I have tried with the code below.
$source = $_FILES['Filedata']['tmp_name'];
$targetFile = '/usr/local/WowzaMediaServer-3.1.1/content/video.mp4'
move_uploaded_file($source,$targetFile);
But it is not working. Can we done it through move_uploaded_file. if not, suggest a better option to do this.
I have seen some similar question but nothing helps. So any help would be appreciated..
Are you sure you're not in a chroot jail?
If so, your "absolute" path name could be pointing to the wrong place-- somewhere that doesn't exist.
If so, change the path to point to somewhere within the jail.
It may be necessary to mount --bind the directory you want this to go in into some location within the jail. (Note that a symbolic link will not work for getting out of jail.)
More than likely this is a simple permissions issue and quite easy to solve.
Find the user that apache uses. To do this open up your httpd.conf file and look for something like:
User apache
Group apache
Change the ownership of the folder that you're trying to upload to.
chown -R apache.apache /usr/local/WowzaMediaServer-3.1.1/content/
Change the permissions of the folder
chmod -R 775 /usr/local/WowzaMediaServer-3.1.1/content/
And that should be that.
I'm going to assume you're using Apache for the purposes of this answer.
First off, is the file being uploaded ok? One possible reason you might have trouble is that the tmp directory isn't writable by the webserver, or readable come to that. Assuming that's ok then move_uploaded_file should work fine.
Create a folder next to your DOCUMENT_ROOT, let's call it "filestore". Make sure it's writable by www-data or whichever user runs apache. Now, you should be able to move the files into that folder. Note they will be owned by www-data:www-data typically - or whatever user and group your server is set up to run as. The reason I put the "filestore" folder next to the DOCUMENT_ROOT folder is that you can be sure the webserver can read the file path up to DOCUMENT_ROOT. Otherwise you run the risk of a folder part way up the path not being readable, and that'll stop you dead. e.g. if you have /usr/local/media as your target folder and /usr/local isn't readable (and executable) by the webserver, you're toast.
If all this works and you absolutely must have you media elsewhere, you can have the "filestore" folder anywhere so long as the whole path to it is read/executable by the webserver. Check each directory in the path.
If these uploaded files are being downloaded by other users via the web then the "filestore" folder only needs to have permissions of 700 since it's always going to be the web server's user which reads them. If other users need access, typically because other software running as a different user needs to use them then you might need permissions to be 750 to allow group members to read (and execute) the directory. You'll also need to add that other user to the www-data group.
For downloads you will need to write a simple script which dumps the file to the browser after doing some authentication checks. That way, you avoid having the media accessible just via http without having any authentication done first - which could make your service into an attractive place for illegal files (copyright violations being the least concern here).
This is a dangerous approach as it gives root privileges to the apache user, so use with caution.
Add the apache user to the list of sudoers - which will let you execute commands as root in php via system('sudo the_command'). Then move the uploaded file to a temporary location that the apache user can write do (eg. create a 'tmp' directory in the doc root). Then use system("sudo mv \"$source\" \"$destination\""); to move the temporary file to it's final location.
You can find the apache user by executing <?php echo exec('whoami'); ?>. Then add the following entry to sudoers the-apache-user ALL=(ALL) NOPASSWD: ALL. Use visudo to add the sudoer entry.
Example:
$source = $_FILES['Filedata']['tmp_name'];
$targetFile = '/usr/local/WowzaMediaServer-3.1.1/content/video.mp4'
$tempLocation = 'tmp/temp-file.mp4';
move_uploaded_file($source, $tempLocation);
system('sudo mv "' . $tempLocation . '" "' . $targetFile . '"');
Edit: Related question - How to run PHP exec() as root?
Always you face a problem with your code, look at the server log or easier turn on errors display. That said, your problem could be related to upload_tmp_dir setting. Check what a phpinfo() tells about that or look at your php.inifile.
A better solution would be to write the file somewhere where you can write (i.e. under the webroot) and then create a symlink from the media directory to be to where you wrote it.
For example:
Web Root is /var/www/html
You want it at /usr/local/WowzaMediaServer-3.1.1/content/
Create directory /var/www/html/mediaserver/content/
Make permissions on /var/www/html/mediaserver/content/ 777 (so apache can write to it)
Copy files from /usr/local/WowzaMediaServer-3.1.1/content/ to /var/www/html/mediaserver/content/
Delete /usr/local/WowzaMediaServer-3.1.1/content/ (just the "content" directory)
Create symlink from /usr/local/WowzaMediaServer-3.1.1/content/ to /var/www/html/mediaserver/content/
Then you have permissions to read/write, and the media server should too. Only issue would be if the media server is trained not to read symlinks - but you can find that out quickly enough.

php file_exists is returning false even if file exist on my linux

This question has been asked many times, but none of the answers I found helped me.
I am trying to get php file_exists() to work. The only scenario when it works is when the php-file is in the same directory as the file to use file_exist() on and only using the file name (i.e. excluding the path). But it's not consequent behaviour, please see below.
Som information:
safe_mode=off
no symlinks for directory 28
no whitespace in the file name
All directories in /var/www/html/smic/upload/28/ has apache:apache 777 as permission.
Using php 5.3
PHP:
echo getcwd()
clearstatcache();
$file = 'file:///var/www/html/smic/upload/28/ul.txt';
//Also tried like this
//$file = '/var/www/html/smic/upload/28/ul.txt';
if(file_exists($file)){
echo $file." exists";
}
getcwd() prints /var/www/html/smic/modules/core/ticket
The permission of the php-script and the file to be checked is apache:apache 777.
Some details about the directory structure:
[root#localhost 28]# pwd
/var/www/html/smic/upload/28
[root#localhost 28]# ls -l ul.txt
-rw-r--r--. 1 apache apache 2 Feb 9 10:50 ul.txt
[root#localhost 28]# chmod 777 ul.txt
[root#localhost 28]# ls -l ul.txt
-rwxrwxrwx. 1 apache apache 2 Feb 9 10:50 ul.txt
The behaviour didn't change after changing the permission of the file. The directory /28 has drwxr-xr-x. for apache user and apache group
For test, I also moved the actual php-script to /28, gave it apache:apache 777 rigths. Changed the $file to "ul.txt" (i.e. $file = 'ul.txt';). That works, the ul.txt file is found.
getcwd() prints then /var/www/html/smic/upload/28
As another test I tried to find another file excluding the path in the "ticket" directory, the file wasn't recognized.
I'm banging my head...
Any advice is appreciated.
The permission of the file alone is not sufficient for php to assess file_exists. the process that runs php also needs permission to traverse all the parent directories of that file to get to it.
Check them one by one and verify that php can read and enter (r-x)
ls -ald /var
ls -ald /var/www
ls -ald /var/www/html
ls -ald /var/www/html/smic
ls -ald /var/www/html/smic/upload
ls -ald /var/www/html/smic/upload/28
Clutching at straws here...
Try su - apache (or whatever the user your webserver runs as.. apache2, www-data etc..) and then traversing the directory.
Are there any .htaccess files knocking about, or any other restrictions on your apache configuration?
Gee, this was a pretty tuff one. I always make sure when I copy anything from the web to first paste it into a normal texteditor in order to remove all strange/hidden characters, then copy the whatever again and paste it into my dev tool.
As I mentioned somewhere in a comment, I did pwd and copied the text form my virtual server to my osx. But what I didn't think about/know was that strange/hidden characters could follow if I did that from my linux server, hence I didn't make sure to copy everything via texteditor.
I remembered that I had problem quite some time ago when I copied from the web and figured this may be a similar kind of problem. I opened my script in an hex editor. And what did I find... '/var' looked lite this: '/var'. Removing the strange characters fixed the problem.
Thank you all for your comments above. Hope those can help someone else and perhaps it has helped me without even knowing it (since I did a lot of things based on your comments).
what's about the access rights to the folder?
the path $file = 'file:///var/www/html/smic/upload/28/ul.txt'; is incorrect.
Try the php script copy to folder upload and file='28/ul.txt';.
The folder must be readable.
Try to open the file using $file = '/upload/28/ul.txt';
From the php.net manual, "Upon failure, an E_WARNING is emitted." make sure error reporting is set to a level that will show warnings and try it.
Also, "This function returns FALSE for files inaccessible due to safe mode restrictions. However these files still can be included if they are located in safe_mode_include_dir.". You're not running in php safe mode are you? phpinfo() should tell you.
Where is your php file located? If within the "html" folder, then use a relative path like $file = "smic/upload/28/ul.txt";
Perhaps, in a name of the file there is a whitespace symbol. It's important.

PHP File Permissions... getting it "write"?

I am trying to write an install script for a system I have been working on. The script copies some default files from one location to another, and creates various folders for them. I have this bit working a treat, but the only problem is that when I login via FTP, I can't edit, or delete the files that PHP has moved for me.
If I login via terminal I can happily "sudo chmod -R 777 [dir]" and the problem goes away, so the question is:
What am I missing on the PHP end?
my permissions function is as follows:
function set_permissions($file)
{
if (file_exists($file)):
chmod($file,0777);
endif;
}
I understand it's not 100% ideal to set the permissions to 777, but I am simply trying to achieve the result of being able to edit the files via FTP, after PHP has moved them for me.
Hope I've been clear enough. This is puzzling me now so any help is appreciated :)
Tom
edit:
The whole process is as follows:
mkdir($root_dir, 0777);
mkdir($images_dir, 0777);
if (!copy($orig_logo, $new_logo))
{
echo "failed to copy $orig_logo...";
}
// see function above for details on set_permissions...
$this->set_permissions($new_logo);
}
(All the paths are correct too)
edit:
The file before I login via terminal has the following permissions:
-rwxrwxrwx 1 www-data www-data 2739 2009-08-26 01:45 base.css
The file after I login and change it has:
-rwxrwxrwx 1 www-data www-data 2739 2009-08-26 01:45 base.css
The system is a content management system that allows you to edit and delete files through the admin area, and strangely enough, this works well. It seems like the files are somehow locked out from anybody else other than Apache... but the file info suggests otherwise. It's odd...
Sounds like your directory needs the write permissions as well.
Are you sure the file exists or the path is correct?
If you can chmod -R 777 via terminal to fix the problem, then what were the permissions set to by PHP before you ran chmod??? Obviously not 777. My guess is that your PHP code is not actually changing the permissions.
Lookat at your code, your permission-changing function could be failing silently if the file doesn't exist - e.g., you're giving it invalid file names (wrong folder? wrong relative path?) but you can't tell because your set_permissions() function is too scared of warning you. You should rewrite it as follows:
function set_permissions($file)
{
if (!file_exists($file))
throw new Exception(__FUNCTION__ . "() file doesn't exist! '$file'");
chmod($file,0777);
error_log("chmod 777 $file"); // debug
}
This allows you to see what's happening, and you'll certainly notice if you haven't got your file names correct.

Categories