I tried to run this command:
php -r "touch('/mnt/my_drive/test.txt', 1600981328);"
I got this error:
PHP Warning: touch(): Utime failed: Operation not permitted in Command line code on line 1
If I run it with sudo, I don't get the error.
/mnt/my_drive is an NTFS drive. The mount was created in fsab with umask=000, so I have no idea, why do I get permission error.
Please do not mark this as a duplicate, because the similar questions have these answers:
Check the permissions: It should be right because of umask=000
Run composer/php in elevated mode: I would like to avoid running the webserver as admin
Modify some library files in vendor: I get this error even in command line, as my example shows
Don't use ntfs: It is not my choice
This may happen when the user PHP runs as isn't the owner of the cache files. Checkout this link Utime failed: Operation not permitted
Your code worked perfectly on my machine with php7.4 and ntfs mounted with:
/dev/sdaX on /mnt/tmp type fuseblk rw,relatime,user_id=0,group_id=0,allow_other,blksize=4096)
Are you sure the directory you are trying to do this in allows you to create files? Does the directory exist?
If you can create normal files without setting the time parameter it might have something to do with ntfs or fuse mounting it.
In this case:
Try to run the php command in strace to see what actually fails, that should help nail down the error.
EDIT: Also the umask should not matter in this case, what matter are the permissions of the directories that contain the file.
Updating file modification time fails unless issued by the owner. Try to clear the cache files and recreate them with the PHP user as the owner.
It is never assumed a good point to change modification times, unless there is a need to file something in with others. It's hasty and shows no function to it. The only thing i can tell you is that you have to own the file, you may need root, just to access these permissions and that with sudo you can do anything. So you've no hope of this. I hope that can bring you to believe in some other way of a file system breakdown for your clients.
Related
I have a SQLite database that I am using for a website. The problem is that when I try to INSERT INTO it, I get a PDOException
SQLSTATE[HY000]: General error: 8 attempt to write a readonly database
I SSH'd into the server and checked permissions, and the database has the permissions
-rw-rw-r--
I'm not that familiar with *nix permissions, but I'm pretty sure this means
Not a directory
Owner has read/write permissions (that's me, according to ls -l)
Group has read/write permissions
Everyone else only has read permissions
I also looked everywhere I knew to using the sqlite3 program, and found nothing relevant.
Because I didn't know with what permissions PDO is trying to open the database, I did
chmod o+w supplies.db
Now, I get another PDOException:
SQLSTATE[HY000]: General error: 14 unable to open database file
But it ONLY occurs when I try to execute an INSERT query after the database is open.
Any ideas on what is going on?
The problem, as it turns out, is that the PDO SQLite driver requires that if you are going to do a write operation (INSERT,UPDATE,DELETE,DROP, etc), then the folder the database resides in must have write permissions, as well as the actual database file.
I found this information in a comment at the very bottom of the PDO SQLite driver manual page.
This can happen when the owner of the SQLite file itself is not the same as the user running the script. Similar errors can occur if the entire directory path (meaning each directory along the way) can't be written to.
Who owns the SQLite file? You?
Who is the script running as? Apache or Nobody?
For me the issue was SELinux enforcement rather than permissions. The "read only database" error went away once I disabled enforcement, following the suggestion made by Steve V. in a comment on the accepted answer.
echo 0 >/selinux/enforce
Upon running this command, everything worked as intended (CentOS 6.3).
The specific issue I had encountered was during setup of Graphite. I had triple-checked that the apache user owned and could write to both my graphite.db and its parent directory. But until I "fixed" SELinux, all I got was a stack trace to the effect of: DatabaseError: attempt to write a readonly database
This can be caused by SELinux. If you don't want to disable SELinux completely, you need to set the db directory fcontext to httpd_sys_rw_content_t.
semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/railsapp/db(/.*)?"
restorecon -v /var/www/railsapp/db
I got this error when I tried to write to a database on an Android system.
Apparently sqlite3 not only needs write permissions to the database file and the containing directory (as #austin-hyde already said in his answer) but also the environment variable TMPDIR has to point to a (possibly writable) directory.
On my Android system I set it to TMPDIR="/data/local/tmp" and now my script runs as expected :)
Edit:
If you can't set environment variables you can use one of the other methods listed here: https://www.sqlite.org/tempfiles.html#temporary_file_storage_locations
like PRAGMA temp_store_directory = 'directory-name';
In summary, I've fixed the problem by putting the database file (* .db) in a subfolder.
The subfolder and the database file within it must be a member of the
www-data group.
In the www-data group, you must have the right to write to the
subfolder and the database file.
####### Additional Notes For Similar Problem #####
I gave write permissions to my sqlite database file to other users and groups but it still didn't work.
File is in my web root directory for my .NET Core WebApi.
It looked like this:
-rw-rw-rw- 1 root root 24576 Jan 28 16:03 librestore.db
Even if I ran the service as root, I kept getting the error :
Error: SQLite Error 8: 'attempt to write a readonly database'.
I also did a chown to www-data on the librestore.db and I still received the same error.
Finally I moved up above my webroot directory and gave others write access to that directory (LibreStore - the root of my WebApi) also and then it worked.
I'm not sure why I had to give the directory write access if the specific file already had write access, but this is the only thing that worked.
But once I made that change www-data user could access the .db file and inserts succeeded.
I got the same error from IIS under windows 7. To fix this error i had to add full control permissions to IUSR account for sqlite database file. You don't need to change permissions if you use sqlite under webmatrix instead of IIS.
I used:
echo exec('whoami');
to find out who is running the script (say username), and then gave the user permissions to the entire application directory, like:
sudo chown -R :username /var/www/html/myapp
(For followers looking for an answer to a similar question)
I'm building a C# .Net Core 6.0 WPF app. I put the Sqlite.db3 on the c:\ drive for convenience while developing. To write to the database I must open Visual Studio 2019 as Administrator.
#Charles in a comment pointed out the solution to this (or at least, a botch solution). This is merely me spelling it out more clearly. Put file_put_contents('./nameofyourdb.sqlite', null); (or .db, whichever you fancy) in a .php file in the root directory of your app (or wherever you want the db to be created), then load that page which renders the php code. Now you have an sqlite db created by whichever user runs your php code, meaning your php code can write to it. Just don't forget to use sudo when interacting with this db in the console.
A good clean solution to this is to allow the file of your main user account to be written to by (in my case) the http user but this worked for me and its simple.
None of these solutions worked for me and I suppose I had a very rare case that can still happen. Had a power shortage so even with 777 permissions on folder and db file, without SELinux, I would get this error.
Turns out there was a jellyfin.pid file (not sure if it's named after the service or user as they have the same name) locking it after the power shortage. Deleted it, restarted the service and everything worked.
I got this in my browser when I changed from using http://localhost to http://145.900.50.20 (where 145.900.50.20 is my local IP address) and then changed back to localhost -- it was necessary to stay with the IP address once I had changed to that once
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 am getting a php warning on my session_start(). You can see the functional code here
I am trying to set the temp directory to a directory with write permissions (chmod 777 temp) and it works. However, after the project is published with runnable the permissions for the temp directory is lost.
So other runnable examples seem to work, why is it that mine does not?
Here is the full error for reference: Warning: session_start(): open(/var/www/temp/sess_mgavllqdlnl36argo108k4d1p6, O_RDWR) failed: Permission denied (13) in /var/www/index.php on line 3
The issue is that with the way aufs works, permissions can't be upgraded (it's more complicated than that, but for effectively that's how it is right now).
We've created a new base php project with the file permissions fixed.
If you fork off of http://runnable.com/UobuRXxMTRlWAAAJ/write-to-a-file-in-php things should work.
Ok, it looks like theres something a bit off with runnable. When you click the arrow next to "run" you have a few options:
Anything that runs through "Web" (even if done through "Web & Terminal") doesn't have write permission. Anything run through terminal does.
Change the run type to "Web & Terminal" and see if you get issues then. Here's an example:
Code
Web
Terminal
My only advice is to open a ticket or otherwise contact runnable.com with this. Alternatively, you can just show output to users via terminal.
session_start must be called before any output is sent, such as your <html> and head stuff.
I'm using move_uploaded_file() to upload images to the server, however it gives the usual error of:
Warning: move_uploaded_file(upload/file.png) [function.move-uploaded-file]:
failed to open stream: No such file or directory in
/home/newuser/public_html/model/account.class.php on line 39
Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move
'/tmp/phpuLkUgE' to 'upload/file.png' in
/home/newuser/public_html/model/account.class.php on line 39
This is not permission based as I have set the folder to 777 with root access and ls -l displays it correctly as this.
755 /home/newuser/public_html/model
755 /home/newuser/public_html/model/account.class.php
777 /home/newuser/public_html/upload
PHP Line
move_uploaded_file($_FILES["photo"]["tmp_name"], "../upload/file.png");
The problem I think is down to the Owner/Group setting being configured incorrectly .. a while back I had all of my sites as subdomains in one account:
/home/olduser/public_html/subdomains/index.html
I then changed this and created a new user account to manage a separate website easier and just moved the files across ...
/home/olduser/public_html/subdomains
/home/newuser/public_html/index.html
The new folders in /home/newuser are now owned and grouped as newuser newuser but I think php may be running as nobody olduser so this could be causing the issue?
What can I try to fix this?
Permissions to a particular file / directory don't just apply on the directory itself, but on the whole path leading up to it.
Example:
/home/ - needs 'x' permission (execute)
/home/newuser/ - needs 'x' permission
/home/newuser/public_html/ - needs 'x' permission
/home/newuser/public_html/avatar/ - needs 'wx' permission (execute + write)
It was kind of touched on indirectly in Silver89's feedback under Jack's Answer, but not outright stated - so I wanted to provide an answer to what helped me with this issue which had me scratching my head for a long time. ;)
The best approach that I have found for the destination of move_uploaded_file() is to use the full absolute path. It can vary based on whether you are on a Unix\Linux server or Windows server, but this should give you the basic idea.
On my Unix server at work, you cannot use "../anything" but have to use the full absolute internal file path of /var/www/html/uploads/imagename.jpg.
So that is why your last test worked for you, Silver89 - because your server was probably trying to upload the image to http://yourservername.com/upload/file.png instead of http://www.yourservername.com/yoursubfolder/upload/file.png. It probably threw out the "../" part altogether and that folder didn't exist on the server.
You can find out what that full path name is by logging onto the server (terminal/ssh etc.) and issuing the 'pwd' command or by using PHP code and echoing the getcwd() command in a stripped php file in the folder where your images will go.
This site is helpful in figuring this out based on your server using different PHP Server Config Checking Functions - See the table midway down. You can simply echo these out to the screen such as:
echo $_SERVER["SCRIPT_FILENAME"].
This was a tough one for me so I hope this makes it a little easier for the next person to find - even if this is 8 months old. ;)
I'm running a script that makes some changes to the contents of a file then resets its modification time to what it was before. Intermittently, I'll find the following errors in my log:
touch() [function.touch]: Utime
failed: Operation not permitted
This on the line immediately after a file_put_contents() call appears to have changed the contents of the file I tried to touch(). There are no errors associated with the file_put_contents() line.
Has anyone had this happen? Can anyone figure out what set of permissions would allow me to write a file but not change its modification time? I'm doing this on Linux.
This is a bug with PHP's touch command. Even if you have write permission to the file, it fails if PHP isn't also the "owner".
If you're using Apache and Linux, use this command on your server's console to make PHP the file's owner:
sudo chown www-data:www-data /YourPATH/YourFILE
Better still, update the entire folder containing files you want PHP to control:
sudo chown -R www-data:www-data /YourPATH/YourFOLDER
Side Note: Because PHP can write to the file, that means it must have user or group write permission. Since that's the case, touch should not behave this way. It seems like a bug.
It could be possible that the file gets created with wrong permissions. Try to chmod 777 the file just after the file_put_contents and then touch the file.
As rossoft says, PHP is probably not the owner of the file. But setting the permissions to 777 might not be the best solution. I'd preferr:
function touch_file($file) {
fclose(fopen($file, 'a'));
}
touch_file('/path/to/file');
Only recently, I've had a similar problem and I think I know the answer.
The actual purpose of touch() is to update the modification and access times of a file. Creating the file is just a side-effect.
If you're using Linux, but writing to an NTFS partition as you might with a dual-boot configuration, depending on how the partition is mounted, touch() might have problems changing the access time on files. The file will be created, but touch() will still fail because the underlying system returns an error status. The same thing can be observed from the command line where you'll get a "permission denied" message.
There doesn't seem to be any documentation regarding this in the man pages for mount, ntfs-3g, or touch (Linux command), but the problem is mentioned in the comments on the touch() PHP function page.
Tweaking mount options might provide a solution, but you're better off using is_writable() to check permissions and fopen() to create files.