Apache is not respecting my default permissions when writing files - php

I'm using Laravel, and whenever the logs or the cache is being written to the storage folder, it's giving 755 permissions, and creating the owner as daemon. I have run sudo chown -R username:username app/storage and sudo chmod -R 775 app/storage numerous times. I have even added username to the group daemon and daemon to the group username.
But, it still writes files as daemon, and with 755 permissions, meaning that username can't write to it.
What am I doing wrong?

This one has also been bugging me for a while but I was too busy to hunt down a solution. Your question got me motivated to fix it. I found the answer on Stack Overflow.
In short, the solution is to change the umask of the Apache process. The link above mentions two possible places to make the change: you add umask 002 to
/etc/init.d/apache2
/etc/apache2/envvars (Debian/Ubuntu) or /etc/sysconfig/httpd (CentOS/Red Hat), or
Edit
I recently upgraded from Ubuntu 12.04 32-bit to 14.04 64-bit and, to my great irritation, I could not get this to work. It worked for some PHP scripts but not others - specifically, a short test script I wrote worked fine, but the Laravel caching code did not. A co-worker put me on to another solution: bindfs.
By mounting my project directory (/var/www/project) in my home directory (~/project) with the appropriate user mapping, all my problems were solved. Here's my fstab entry:
/var/www/project /home/username/project fuse.bindfs map=www-data/username:#www-data/#usergroup
Now I work in ~/project - everything looks like it's owned by username:usergroup and all filesystem changes work as if I own the files. But if I ls -la /var/www/project/, everything is actually owned by www-data:www-data.
Perhaps this is an overly-complicated solution, but if you have trouble getting the umask solution to work, this is another approach.

In this instance Apache isn't doing anything wrong. Apache reads and writes files based on the User and Group settings in its configuration file. The configuration file in question is like /etc/httpd/conf/httpd.conf but the location and even name differs depending on the system you're using.
It's also worth noting, that if you're running PHP as something such as FastCGI, then it'll use the user that FastCGI is set to use, seeing as that is the bit that modifies and creates files, not Apache.

Related

A unix user seems to be usurping www-data when PHP executes curtain functions

I'm running a LAMP stack on a linode. The Ubuntu version is Lucid.
When a PHP script executes a mkdir() or move_uploaded_file command, the newly created folder/file winds up being owned by a unix user 'Grusha'. I did create this user, but it should not be owning files. The web folder overall is owned by www-data, as is (by extension) the containing folder inside which the new folder/files are moving.
The user's /etc/passwd line is like this:
grusha:x:1000:1003:,,,:/home/grusha:/bin/bash
And /etc/group is this:
grusha:x:1003:
Grusha owns the PHP sessions as they're created too, although nothing else. No processes or files on the system run as Grusha either.
I log in with a public key, and the user who that goes through is not Grusha (nor root).
When I delete Grusha, I can no longer restart Apache. I get bad username and the restart fails. My PHP sessions also don't work.
So in the end I add Grusha again and the server will start and everything works except that scripts make files owned by Grusha, not www-data.
I've been looking around as much as possible, but can't find any info. My httpd.conf is empty. My apache2.conf contains these lines:
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
And those variables are defined as www-data in /etc/apache2/envars.
If anyone has any suggestions I'd be grateful.
Thanks a lot,
Elliot
The suPHP module is probably enabled. Its function is to let PHP code execute under the user ID of the user who owns the scripts, instead of www-data, which can be very insecure on a shared server. Try turning off suPHP by deleting /etc/apache2/mods-enabled/suphp.load and /etc/apache2/mods-enabled/suphp.conf.
On the off chance that's not the problem, check that the user grusha doesn't actually have the same numeric user ID as www-data (in /etc/passwd). That's probably unlikely though.
Ah, this is solved. Apologies.
I had mpm directives in /etc/apache2/sites-enabled/ that caused apache to run as grusha.
Unsure how that happened, but it's fixed in any case.
Thanks to you both for thinking about my problem.

chown in scripts

Update: turns out the problem is more complicated than I originally thought. I was simultaneously trying to troubleshoot why my mkdir stopped working and it was because I had manually changed permissions of the parent directory to test then switched them back and added a chmod to the script which doesn't work since that one is being run by apache and not myself. I'll be posting a new question with the larger problem as I think adding all of this into this one will become confusing.
I'm a lab instructor at my university and I've been rewriting the script they provide for uploading assignments because the one they have is old and buggy. Instead of modifying the existing script (written in python) I've been writing it from scratch in php.
I've come across an issue where it seems that chown is not working. The php scripts run under the user apache. I'm not sure if that user is 'priveleged' or not but the original script used chown.
Can I assume that therefore apache should have the needed authority and that my issue lies elsewhere or is that faulty logic?
The server is the university's and there is no way they will let me make any configuration changes. I do believe that it is CentOS that they're running. There is no error message i just noticed that I can chmod the file and change the permissions but that the chown command on the next line seems to have no effect.
ls -al on the old scripts show:
-rwxr-xr-x 1 mattw labstaff 5067 Sep 1 17:52 File_Upload.cgi
Doesn't look like the setuid bit is on.
Stefan mentioned "The user apache most likely doesn't have enough permissions to chown a file/folder it does not own". The directory I'm attempting to chown was just created with a mkdir so it should be owned by apache. Should chown work regardless of privilege when you already own the file?
Apache probably doesn't have the privileges to do so. It depends on which environment it's running in. You said apache is running under the user apache, so I'm just going to assume that it's RHEL or a RHEL variant such as Centos.
You would be able to edit the sudoers file (with visudo) and give apache the ability to sudo without a password under a certain directory. Be aware that this isn't recommended if you're very security conscious.
Adding something like
apache ALL = NOPASSWD: /bin/chown 1[1-9][0-9][0-9]\:1[1-9][0-9][0-9] /var/www/[a-zA-Z0-9]*
You may be able to add apache to a different group, or another user to the apache group or something of the sort and chmodding it to 0775 or 0664 instead.
It would be best to post the code that's throwing the error, the error message if any, and which users and groups need access to the files being uploaded.
If the old script is run by the apache user but is able to execute chown it may have the setuid bit on to allow it to run with elevated privileges. In that case your assumption would be wrong.
Please post the output of ls -al /path/to/script to confirm this. It should show root as its owner and a s in its mode.
To enable setuid mode for the new script, chmod u+s it. Do note this may have serious security implications. In particular never leave a setuid script or binary writeable.
The user apache most likely doesn't have enough permissions to chown a file/folder it does not own, you can give apache more rights however this could become a security concern.

Ubuntu Xampp PHP File Permissions with NTFS Hdd's as additional media storage

I have 4 drives in my (yes, physically in the box, sata connected) Ubuntu 10.10 system with xampp installed at the /opt/lampp/ dir on the OS drive. The OS drive (ssd, lets call it drive1 for sanity) has the correct file permissions to allow for PHP (user www-data) to read/write to any of my htdocs and vhosts folder(s).
My problem comes with I try to move a file that exists on one of the other 3 drives. Each of my other drives are ntfs (1tb, 1.5tb and 2.0tb) and mounted with fstab. When I view the file permissions with the gui (nautilus) it says that everything is root. So I tried chown, chmod, etc. I found out that you can't change the permissions of ntfs with those commands. So I went to my fstab config, however I can't get those permissions set to allow for PHP to copy/rename/move a file within even one of the drives.
I updated to using the UUID's today, the drives are also shared on my local network and that still works just fine.
I changed to the ntfs-3g driver after installing, restarted the machine but I'm still not able to have php move a file.
Here is my fstab file:
UUID=552A7C6B05CEAAD2 /media/v1tb ntfs-3g defaults,uid=1000 0 0
UUID=DE58539158536775 /media/v1.5tb ntfs-3g defaults,uid=1000 0 0
UUID=3D80C54D5D100280 /media/v2.0tb ntfs-3g defaults,uid=1000 0 0
Also, I tried to use the following and its working just fine:
sudo -u www-data cp '/media/v2.0tb/path/to/file' '/media/v2.0tb/path/to/newfile'
How does imitating a user work, but php's rename/copy functions won't work?
How can I set the php user (www-data) to allow for copying/renaming/deleting files and directories on these ntfs drives? Do I have to reformat them?
Depends on the actual ntfs driver used. For ntfs-3g you can use the uid= and gid= params in the fstab. There is also a usermapping= feature that might be of interest. See also the manpage
If anybody gets a problem like this, sometimes it could be that the permissions on previous directories could affect the access to a directory.
For example, on Ubuntu 12.10, you have the partitions on /media, as many other Ubuntu versions. But on this version, you could have another directory where your partitions, especially the NTFS and external drives, will be located, and is /media/YOUR_USER_NAME. To solve the access to my external hard drive, concretely using PHP, I had to change permissions at /media/MY_USER_NAME, first, and then at /media/MY_USER_NAME/MY_EXTERNAL_DRIVE.
These are the commands used:
sudo chown MY_USER_NAME MY_USER_NAME/
sudo chown MY_USER_NAME MY_USER_NAME/MY_EXTERNAL_DRIVE/
and
sudo mount -t ntfs -o rw,uid=1000,gid=1000,fmask=000,dmask=000 /dev/sdb1 /media/MY_USER_NAME/MY_EXTERNAL_DRIVE
The first and the second one, is to change the Owner of the directory, and the third one, to mount the NTFS drive with the correct permissions.
I've thought this could be usefull to somebody, cause I've spent several hours after I realized that it could be that I couldn't access to previous directories.

Apache permissions, PHP file create, MKDir fail

It seems i cannot create files. When i set permissions to 777 On the folder i am trying to create a folder in then the script works fine. If the folder is set to 755, it fails. I do not know much about linux, but i am suppose to figure this stuff out. I have spent a couple hours trying stuff. Does anyone know how to make it so that apache has high enough permissions.
I know it is a permissions and apache problem, i just do not know how to fix this. I have edited the httpd.conf file, but i really do not know what i am doing... Any help? (I saved backup.)
Please stop suggesting to use 777. You're making your file writeable by everyone, which pretty much means you lose all security that the permission system was designed for. If you suggest this, think about the consequences it may have on a poorly configured webserver: it would become incredibly easy to "hack" the website, by overwriting the files. So, don't.
Michael: there's a perfectly viable reason why your script can't create the directory, the user running PHP (that might be different from Apache) simply doesn't have sufficient permissions to do so. Instead of changing the permissions, I think you should solve the underlying problem, meaning your files have the wrong owner, or Apache or PHP is running under the wrong user.
Now, it seems like you have your own server installed. You can determine which user is running PHP by running a simple script that calls the 'whoami' program installed in most linuxes:
<?php
echo `whoami`;
If all is right, you should see the username PHP is running under. Depending on your OS, this might be 'www-data', 'nobody', 'http', or any variation. If your website is the only website running, this is easy to change by changing the user Apache runs under. If you have Debian, like I tend to, you can edit the file /etc/apache2/envvars (as root), and change the value for APACHE_RUN_USER. Depending on your OS, this variable might be set in a different configuration file, so if you can't find it in /etc/apache2/envvars, try to search for the variable declaration by using:
$ grep -R "APACHE_RUN_USER=" .
From the directory all apache-config files are in.
If you're not the only one on the server, you might want to consider creating user accounts for every website, and using something like Apache2-MPM-ITK to change the RUN_USER depending on which website is called. Also, make sure that the user the PHP process is running under is the owner of the files, and the directories. You can accomplish that by using chown:
% chown theuser:theuser -R /var/www/website/
If PHP is running with it's own user, and is the owner of the files and directories it needs to write in, the permission 700 would be enough. I tend to use 750 for most files myself though, as I generally have multiple users in that group, and they can have reading permissions. So, you can change the permissions:
% chmod 0750 -R /var/www/website/
That should be it. If you having issues, let us know, and please don't ever take up any advice that essentially tells you: if security is bothering you, remove the security.
I have a similar problem but in my case I have SELinux running and it failed even with 0777 permission. Turns out I need to explicitly allow httpd to have write access on the directory using:
chcon -R -t httpd_sys_rw_content_t <PARENT_OF_MKDIR_TARGET>
SELinux Troubleshooter may have more details.
On ubuntu you edit /etc/apache2/envvars as Berry suggested.
When you change the Apache user, beware of unintended consequences. One of them is the PHP sessions that may be stored in /var/lib/php5. You may need to change the ownership of that folder too.

CHMOD a linux directory using PHP on an apache server

Has anyone ever used PHP (proven and successful) to CHMOD a directory through a Web Browser?
My roadblocks are:
(a) PHP script runs as "nobody" from the browser
(b) directory above the one I want to CHMOD is owned by the ftp user and "nobody" does not have write permissions to it
So when I try to chmod 0666 /usr/www/dirOwnedbyFTPuser/dirIamTryingToCHMOD/ I get Permission denied
If you have ever written and successfully run a script to do this, can you share the snipit of code with me? Thanks...been at this for months.
Yes it is possible to do this via php. Usual linux permissions rules apply however so as you are looking to chmod scripts not owned by the apache user (nobody) and the apache user does not have write permissions then one method is to give apache permission to use sudo
Be warned - this is potentially a massive security hole!!!
You can give apache permission to use sudo by editing the sudoers file. It is recommended that you do not edit this file directly as an error can leave you completely screwed so on my (Ubuntu) system I type
sudo visudo
Then you need to add a line for your "nobody" user. You can restrict sudo permissions to a particular script or folder so i would recommend writing a shell script to change the permissions and then placing this in a folder away from any other scripts. That way apache doesn't have complete root privileges on your system (which is a pretty scary thought). You can also put some code in the shell script to restrict which files can be changed.
You also need to allow apache to sudo without a password as you have no way of entering the password through php. So the line you would add is something like
nobody ALL=(ALL)NOPASSWD:/path/to/my/script
Then in php you just prefix the command with sudo
passthru ("sudo /path/to/my/script ...");
(there are a few other functions you can use instead of passthru(), was just the first that came to mind)
As I said before, this is potentially very dangerous and whilst the above will work, I have only used it on my own private system before, never on a public production server. I'm sure plenty of people will have comments on the security of this so I would be interested to hear what other potential pitfalls and security holes there could be with this method. I know a similar thing can be done using SuExec but am not so familiar with it so if anyone has any pros or cons of SuExec over this method I would be interested to hear them.
Final note: I would change the apache user from nobody to something like 'apache' or 'www' - probably just being silly but I don't like the idea of giving root permissions to a user called nobody!!!
Hope this helps!
Yes, you can chmod from php via a web browser. (yes we all know it can be a bad idea)..
But - you can only chmod files that the php script has permission to use! if your web server runs PHP as nobody, then you can chmod any files owned by "nobody"...
http://www.php.net/ftp
You could have php log in as the ftp user and do it.

Categories