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.
Related
So I have a PHP file located in /var/www/html/test.php and I have it run the code shell_exec('touch /home/pi/Desktop/test_file')
However, the webpage displays fine but when I check the apache log files, I always get permission denied. I understand that apache is running as www-data user and my main user pi probably have some permission clash (I'm new to this stuff).
I tried many options I found on-line, the most promising was here, which suggested I run the commands:
sudo chown -R pi:www-data /home/pi/Desktop
sudo chmod -R g+s /home/pi/Desktop
...but I still get permission denied. Can anyone please suggest what permissions I may need to still configure? I want to ensure security, but at the same time need my PHP file to be able to create new files. I used the Desktop as an example directory, but really I don't care which directory, I just need a directory. I tried touching a file within /var/www/html, but that was permission denied as well. Thanks!
if your apache process is running as www-data, and the file ownership is pi:www-data, you probably need to run this chmod:
sudo chmod -R g+w /home/pi/Dekstop
First, setting the group as www-data won't matter if the files are not group writable. Mode 755 will ensure apache can read the files, but the www-data user would still not be able to write.
Secondly, using "g+w" adds group write without messing with any of the other bits. [644 becomes 664, and 755 becomes 775)]. This way you can safely adjust permissions recursively, without making files executable that shouldn't be.
Incidentally, sudo chmod g+s ... is probably not what you want. That will instead set the sgid bit, and not the group write bit.
First of all, why the heck are you using shell_exec to create a file? PHP has it's own touch() function that will do that for you. You can also create files just by opening a nonexistent file using certain modes (ie, fopen("myfile", "w"))
Using exec to create your files is surely messing with your permissions.
You need to find out which user PHP is running as and chown to that user. You can find that out by running get_current_user().
Then you need to change the permissions with chmod. There's an example in the comments so I won't repeat it. Good luck. Stop using shell_exec.
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.
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.
Strangely enough the server can't resize images any more because it doesn't have enough write permissions. When I check the permissions of the directory I want to write my resized images to I see:
username staff
After excecuting echo exec('whoami');
and checking the httpd.conf I saw the user and group for the server was daemon:daemon (this seems to be the default for Zend Server CE on an OSX installation). What should I do so I have enough permissions again. Should I chown my directory to daemon:daemon (what isn't working). Should I change the user of the server or something else?
IMHO there's no point in touching the web server user - it makes sense for Apache to run as a dedicated user and not have access to all your personal files.
The best way to solve this in my experience is to change the file's group to daemon and make it group-writable, but keep you the owner of the file so you can edit / delete it as well. On OS X terminal this is done by:
$ sudo chgrp daemon <file>
$ sudo chmod 664 <file>
Obviously replace <file> with the name of the file you want to give access to.
Another easy way out is to run chmod 666 on the file - make it world writable, but this is not recommended if you care about security in any way (might be ok on your own development environment but never in production or a shared environment).
I really depends on if you are using this in production in the wild or in private. If it were me, I would simply chown the directory for use with the server only. If you give access to that group, you will open up access to many more things.
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.