I have a PHP script that deletes files. It can delete files from my root directory, but when I try to delete from a subdirectory, it says "Permission denied". I know the file exists and PHP can access it because I can read and write to the file, but I can't delete it.
Why?
EDIT: If this is relevant, I am using Zymic hosting. But I have another site on Zymic where the deleting works fine. I don't get it...
EDIT: I use ajax to access the PHP file with the code to delete, and the ajax sends the file name to delete. I know the file name it sends is correct, because the warning message prints it for me. The PHP code is simply:
$file=$_POST['file'];
echo unlink($file);
EDIT: I fixed it! I don't know why this worked, but I FTP-chmodded the directory from 755 to 775 Can anyone tell me why it worked?
To delete the file you need write permissions to the folder that contains it, check that first.
CHMOD xxx -> Owner Group Other
first case:
755 - Owner (read, write, execute), Group (read, execute), Other (read, execute)
second case:
775 - Owner (read, write, execute), Group (read, write, execute), Other (read, execute)
Try to add this at the beginning of the script you're running:
error_reporting(E_ALL | E_STRICT);
That should be able to point out accurately what is going on, chances are that you do not have permissions to write to the folder
Especially if you're working on a Linux environment. In Linux everything is a file, even folders. When it comes to deleting files, you need to be able to write to the file that represents a folder, that's why having permissions to write to the file you're trying to get rid of, does not have anything to do with deleting it.
You have to fclose($myfile) first before using unlink($myfile),,because if it is open on the server by anyone it will not delete it. Also place this script in the same directory as the files you wish to delete,, otherwise you may accidently delete the whole DIR.
Related
I currently have a directory (udir), which has only read and write permissions for all users. This directory contains two files (file1 & file2)
I initially though that only write access was needed (on the directory) for me to be able to delete/remove a file via (rm udir/file1) but the rm command would give me access denied. when i set the permissions to read, write, and execute, the rm command works.
Obviously the execute access is needed as well but why??
I thought the execute access on a directory was to be able to make it a working a directory and search its contents and access sub directories.
You actually need read, write and execute permissions on the directory, not on the file itself since the operation is done considering the permissions effects of directories.
A good documentation can be found on this link, which mentions the below in the section Special Considerations on Directories:
To delete a file requires both write (to modify the directory itself)
and execute (to stat() the file's inode) on a directory. Note a user
needs no permissions on a file nor be the file's owner to delete it!
I'm facing a problem with deleting video files from folder using php unlink() function , image are deleting but when trying deleting videos it says
unlink(file_path) : permission denied.
You (running your script as either through CLI or a webserver) need write access to the directory in which the files are located. so access to the file is not enough.
Your image directory would be different and writable for webserver or cli.
chmod("your/video/dir/path",0777);
try using above code before unlink the video in your script.
Edit: Looks like you are using Windows. Unfortunately, my answer is for Unix-like operating systems (so Linux, MacOS). You could try installing Bash extension for Win8+, but still I'm not sure if this would work. However, I'm keeping my answer in case of anyone with similar problem is looking here for an answer.
Changing permissions through PHP might work in some cases, but not always, because if you don't have permissions to delete the file you might also not have permissions to change them.
The best solution is to create a directory where you will keep files to which PHP will have full access. Let's call it dirname. Once you have created a directory, change its owner and group to the one corresponding to your web server user's name (if you're using Apache, it's "www-data"), for example: chown www-data:www-data dirname.
Once you've done that, change folder's permissions. My suggestion is 744, it will assure that user who owns it will have all permissions, and everyone else will be able only to read it. To do that, execute the following command: chmod -R 777 dirname.
Now you should be able to do anything you want with the files in given directory directly from PHP.
I have a script that uploads a *.csv to import into a DB table that I have which works great in linux through chmod($target, 0777); but I can't for the life of me find the solution to do exactly this but on a Windows based Apache server.
Some other posts have people responding "don't put in the 0777 and it should work" but that's not the case for me. Thanks!
Thanks to the comment left on my original post I was able to figure it out with a little more help from https://web.archive.org/web/20171121192635/http://www.howyoudo.info/index.php/how-to-fix-windows-server-upload-file-inherit-permissions-error/
The problem only happens when you use PHP to upload a file. When you upload a file, PHP sends the file to a temporary directory on the
hard drive (for me it is C:\Windows\Temp) and then copies it over to
it’s intended directory. Once the file has landed in the temporary
directory, it is assigned the permissions of that directory. The
problem is when Windows copies that file, it keeps the temporary
directory’s permissions and doesn’t inherit your web directory’s
permissions.
The easiest way to fix this problem is to add to the temporary directory your intended web directory’s permissions. There’s no need
to erase the permissions already in the temporary directory, just add
the web directory’s permissions to them. In other words, follow these
steps
To change the permissions of your temporary upload directory, find
the “upload_tmp_dir” in your php.ini file.
Set it to the directory
of your choosing (outside your web folders of course) or leave it at
default (for me it is C:\Windows\Temp).
Browse to this folder and add the permissions of your web folders to it.
While Brian Leishman's answer will work, if you do not have the ability to edit permissions on the temp folder, you can make your uploaded file inherit permissions from its new location manually with the following on the command line:
icacls "target.txt" /q /c /reset
So, using PHP's exec() function:
exec( 'icacls "target.txt" /q /c /reset' );
For details of the various icacls flags, see: https://technet.microsoft.com/en-us/library/cc753525.aspx
Tip: Using the /t flag, you can use pattern matching to process multiple files.
I have a file test.php. This write to log.txt in a sub folder log.
I have tried some combinations and it seems minimum is 007 for the folder and 006 for the log. Is this perfect?
First off, test.php should likely execute as a specific user in a user group to whom you give permissions.
Second, you should give permission to write to that group, rather than everyone. The three digits in a permission octal give permission to the owner, group, and everyone else. As you have set your permissions, you're basically letting everyone view your logs and execute stuff in your log folder.
You probably want to give the owner and group full permission to the folder and read/write to the log file while also keeping other people out of the folder. That being the case, you want to set the permissions for the folder at 770 and the file as 660. As long as test.php executes as the user or the group who owns log.txt, it'll work fine and keep prying eyes out.
I wouldn't call it perfect, it depends on what you're trying to accomplish and how your users are setup... thats not exactly minimum either. With that setting EVERYONE can read write and execute for the directory. And EVERYONE can read and write the file.
If you can, the file log.txt should already exist, then you don't need to up the permissions on the folder at all. And I'd only allow read and write on the file for the specific users and groups who need the rights. Its also a good idea to keep writable data above the web root, then if someone does manage to get something into it that shouldn't be there, its not directly accessible on the web.
This is in no way perfect. It means everyone can write to the directory, and everyone is permitted to read and write to the log file.
You should determine the user for which the PHP processes are spawned and set file/directory ownership accordingly. In almost any case, 0700 and 0600 for directory and file, respectively, is sufficient.
007 and 006 are almost definitely not what you want. In file permissions, the last digit is the code for 'world', which is everyone that isn't you.
If your web server is configured with suid or something similar, you can set your permissions to be 770 or 660, or possibly even 700 or 600. These permissions are much more restrictive, which is what you want.
I am trying to set up automated .htaccess updating. This clearly needs to be as secure as possible, however right now the best I can do file permission-wise is 666.
What can I do to setup either my server or php code so that my script's fwrite() command will work with 644 or better? For instance is there a way to set my script(s) to run as owner?
EDIT:
I realized I actually just had a permissions issue, you should be able to use fwrite no problem with 644 permissions. See my answer below.
The apache process should always run as apache:apache - if you must enable write permissions in executable (i.e. DocumentRoot) directories, create a group, add apache and set group write permissions (so 664).
It's best to have .htaccess updated by a cron script reading config data from a database, as giving apache write permissions to executable directories is frowned upon in case a vulnerability in your code allows a malicious user to write new files to those directories.
You can't change the process's owner. If you're on a shared server, see if they have suPHP as an option.
These suggestions were great, however I ultimately realized that the answer to my question is YES - and you shouldn't have to do anything at all... as long as the Owner user of the file/directory you are trying to write to is the same user the script is running as. My mistake was that I accidentally had my file ownership out of whack therefore needed higher permissions 666 and 777 in order to write to my files. Which makes sense because Wordpress can write to .htaccess with standard permissions.
Now I have things setup where a file running as user1 is writing to a file owned by user1:user1, and no problems whatsoever. Directories set to 755, .htaccess file set to 644.