Permission problems with Apache on Centos - php

I've set up a LAMP machine with Centos, apache, MySQL and PHP 7.4.
my user via ssh is mformisano, I'm able to login via SFTP with mformisano and browse folders.
It's an intranet machine, so we are not so severe on restrictions, but, if I type the address into the browser I can execute PHP files, but these files are not able to extract files, create files, etc into the var/www/html folder.
Actually the www folder is:
drwxr-s---. 4 apache apache 31 29 ott 22.34 www
inside:
drwxr-xr-x. 21 root root 4096 29 ott 22.34 ..
drwxr-x---. 2 apache apache 6 19 ott 15.54 cgi-bin
drwxrwxr-x+ 3 apache apache 4096 2 nov 10.49 HTML
If I give permission to mformisano, I can browse via FTP, PHP is executed.
If I give permission to apache:apache I cannot browse, PHP is executed.
If I give permission to mformisano:apache I can browse, PHP is executed.
If I give permission to mformisano:mformisano I can browse, PHP is not executed.
I do need to both browse and execute PHP, so mformisano:apache should be the right way, but when I execute kickstart.php (a WordPress plugin that extracts a .jpa archive) this is not extracting and give me an error about writing permissions.
What am I doing wrong?

The PHP files are going to be parsed by Apache. Typically Apache will be running under the user www-data, in any case find out what user Apache is running under and give the appropriate permissions to the user that apache is running as. If you are a single person running the sever I would recommend SFTP login as root user, this will give you permissions to modify whatever you want on the server, but remember to change the owner and groups for any files you create as root user before logging out.

Related

MAMP - running php-fpm as a different user

I am wanting to change the user from root to user1 but I can't find where the config file is for php-fpm in nginx inside the MAMP directory.
The reason I want to run it as a non root user is because when I upload a file it is created with permissions of the root user but my MAMP folder itself is under user1 and that means that a script that is running under root will never be able to read this file. If I use apache in MAMP it works perfectly because it automatically executes php under user1 like it should.

PHP: get_current_user() vs. exec('whoami')

Short version of the question:
What's the difference between
get_current_user(); and exec('whoami'); ?
Long version of the question:
I'm on a XAMPP Localhost on a Mac.
I'm using Apache, building a PHP
based website in a folder (let's call it folderxyz) within the
htdocs folder (var/www in some flavors of Linux+Apache).
I was playing around with a database connection,
testing out PDO::ERRMODE_EXCEPTION described here: Link
And I got this error:
file_put_contents(PDOErrors.txt): failed to open stream: Permission
denied...
So I did some sleuthing around and it seems that to fix this I need to change the CHMOD settings of file PDOErrors.txt to 777.
However, my questions are about something else. During this process I realized that I don't clearly understand the concept of user in Apache, PHP, and MySQL.
The PHP manual says that get_current_user() "Gets the name of the owner of the current PHP script" Link
The PHP manual says that exec('whoami') returns "the username that owns the running php/httpd process" Link
When I use get_current_user(), I get my firstnamelastname, which is my account name on my Mac.
When I use exec('whoami'), I get daemon.
So...
What's the relationship between firstnamelastname and daemon ?
What's the relationship between the "the owner of the current PHP script" and "username that owns the running php/httpd process" ?
Who needs permission to write to PDOErrors.txt? Is it firstnamelastname or daemon ?
Who needs permission to write to PDOErrors.txt? Is it Apache or PHP (or both) ?
Does the concept of a unix-like root account factor-in anywhere here ?
Edit: I updated this to reflect that it wasn't the folderxyz that I had to change CHMOD settings for. I had to change the settings for the file PDOErrors.txt
OP here: for future reference, I put up a parallel question for the Linux platform here (with an accompanying intuitive explanation of what's going on): https://stackoverflow.com/questions/31389892/why-is-the-output-www-data-in-one-case-and-root-in-another
Update: That question was deleted as it was deemed to be a duplicate of this one (although that was for the Linux platform, and instead of daemon I was getting www-data after doing echo exec('whoami'); ).
This is what I learned from asking this question in the Linux forum:
the running process is different than the script. Yes, the process emerges from the script, but it's not the same thing. The script is owned by root, but the process is taken over by Apache and is run as www-data.
Overall conclusion: What I learned from this process is that user is supposed to be the Apache daemon (Mac localhost) or www-data (Linux on an internet server) and that I should be using exec('whoami') to determine this, and I shouldn't care too much about get_current_user() (which probably should have been named get_current_owner()).
get_current_user() (should) return the owner of the file, which is firstnamelastname in this case. There have been reported issues that this function is inconsistent between platforms however. As such, I would not trust its output. daemon is the user Apache is running as.
The owner of the PHP script is the user who owns the file itself according to the operating system. You can run ls -la in the directory your scripts are in to find the user and group the file belongs to.
Whichever user you're editing your scripts with needs to be able to write it, so most likely, firstnamelastname (+rw).
For the folder itself, you should have +rx (execute and read) for daemon and for the PHP file, +r (read). On my installation of XAMMP, they've done this by setting everything in htdocs as public readable, thus daemon can read it, but not write to it.
Mac has a root account that typically owns the htdocs or www directory. It fills the role of a traditional unix root user.
Here is some information on the file owners/groups and the process owner:
host:~$ ls -l /Applications/XAMPP/xamppfiles/htdocs
drwxr-xr-x 3 root admin 4096 2015-01-01 00:01 .
drwxr-xr-x 3 root admin 4096 2015-01-01 00:01 ..
-rw-r--r-- 1 firstnamelastname admin 189 2015-01-31 20:45 index.php
host:~$ ps aux | grep httpd | head -n1
daemon 45204 0.0 0.1 2510176 10328 ?? S Tue11AM 0:01.38 /Applications/XAMPP/xamppfiles/bin/httpd -k start -E /Applications/XAMPP/xamppfiles/logs/error_log -DSSL -DPHP
If you wanted to make a file writeable by the daemon user, you can create a new folder and name it as the owner with the group admin (so you can use it too), and give it +rwx for the user and group, with +rx for public:
host:~$ cd /Applications/XAMPP/xamppfiles/htdocs
host:htdocs$ mkdir some_dir
host:htdocs$ chmod 775 some_dir

Delete files outside of Web dir?

What is the solution to delete the files outside of web dir? It doesn't delete the files.
Script will be accessed via web browser (only admins).
For example:
PHP located at: /var/www/html/delete_xx_phones.php
-rwxr-xr-x 1 root root 592 Mar 13 17:18 delete_xx_phones.php
delete_xx_phones.php code look something like this:
foreach(glob("/path/004*-phone.cf") as $file) {
unlink($file);
}
Files in /path
-rw-r--r-- 1 root root 346 Mar 13 17:15 004aaaa-phone.cf
-rw-r--r-- 1 root root 346 Mar 13 17:15 004bbaa-phone.cf
PHP scripts often run as user other than root, as they typically are executed by httpd. Since your files are set to have write permissions only for the root user, that's not going to work out.
If you cannot permanently change the ownership or write permission of the files, you could consider writing a very short script and executing it with elevated permissions (using sudo or the suid bit) instead of calling unlink() on PHP.
For the suid approach, write a simple script in Perl (may require perl-suidperl package installed), which deletes the filename passed as an argument:
delete-file.pl:
#!/usr/bin/perl -wT
# This is VERY insecure, so if you use it, make sure you modify it
# to filter the filenames before putting the script on production
# machines
unlink $ARGV[ 0 ];
Make sure the file is owned by root (chown root delete-file.pl) and then run chmod 6711 delete-file.pl to set its SUID bit. After that the file will always execute as root.
Then in your PHP script, you'll just need to run exec( "/path/delete-file.pl $filename" ) (consider shellescapearg() for safety) and your files should start deleting.
(Note that I'm specifically using Perl here because Bash traditionally ignores the suid bit.)
If you feel more comfortable with using sudo, then just write a script similar to what is described above (Bash will work too) and just add it to /etc/sudoers. You can then do something along the lines of: exec( "/usr/bin/sudo /path/to/delete-file-script $filename" ); to run the script with elevated permissions.
The files aren't accessible to PHP because they belong to the root user. PHP usually runs as with the web server's user ID, or if it's running on command line, in the context of the user who called php.
Theoretically, you could do a sudo in your PHP script to forcibly delete those files, but that's very bad practice - you'd have to store the root password in the PHP script for that.
A better way would be to change the files' owner to the user PHP runs as, or chmod ing them so PHP can delete them (although that's also not really elegant because you'd make the file accessible to every user on the machine).
Depending on your situation, a cron script that runs under the root account every couple of minutes and changes the owner of those files might be a workable solution:
chown apache:apache /path/004*-phone.cf
(substitute apache:apache with your PHP user and/or group)
Of course, if you can influence how these files are created, making them the property of the right user straight away would be ideal.

Httpd file permission on Apache server

I've always used the following codes to create a folder on a Apache server but recently on one of the server I've got permission denied error.
if(!is_dir('img/user/'.$id))
{
mkdir('img/user/'.$id, 0777, true);
chmod('img/user/'.$id, 0777);
}
On internet I found that to upload directory for httpd it needs to have write permissions like this:
drwxrwxrwx 2 user staff 512 Jan 07 12:32 uploads/
Where is this permission set? I do not direct access to the server. Is there any alternatively?
You never want to set permissions to be world writable if you can avoid it, or even readable for that matter. 0770 would be a better option, if still a little broad. The main point is that the folder(s) in question need to be writable by the webserver user. For instance, on many webhosts apache will be run by the user nobody, so a more appropriate permission would look like this:
drwxrwx--- 2 nobody nobody 512 Jan 07 12:32 uploads/
Now, there is a problem if you can't get direct access to set permissions yourself except through PHP, because some web hosts will disallow your ability to run chmod or other permissions or ownership modifications from within PHP. That said, if you're using cPanel (and likely other hosting systems do this as well) you can use the online file manager to accomplish what you want by browsing to the appropriate directory and using change permissions located at the top of the page.
So, ultimately, here's what you need: If you need to be able to create a directory in a particular place, you need to make sure that place is writable by the web server. In your example, that means that you need to set appropriate permissions on img/user first before you attempt to create img/user/$id. That means that img/user either must have permissions of 0770 and must be owned by nobody:nobody (either user or group would work in this context, you don't need both), or it must have permissions of 0777. Then, when you create your specific user directory, you can do it like so:
if(!is_dir('img/user/'.$id))
{
mkdir('img/user/'.$id, 0770, true);
}
... because it will already be owned by the appropriate user and you'll already have write access to it simply because your webserver created it in the first place.
If you can't find a non-PHP way to do it, then you'll have to get your webhost to help.
PHP runs as user: www-data in group: www-data (Ubuntu) or something else depending of the server OS.
You can ask your provider to set the right access on maps / files if you cannot do it yourself by FTP.

Who owns a php exec tar extracted file?

As far as file permissions are concerned, when you use a php script to unzip a tar file, who is the "owner" user of the files created?
I'm wondering if its my ftp user because I uploaded the script file? Or does apache own the file? I know their are flags to be set to preserve the original permissions which I don't want (files where created and archived by someone else). I want my user to be the creater/owner of the files.
PS Its a cloud environment.
Below is the code I uploaded. I executed by visiting the page in a browser. I can change file permissions in Dreamweaver... Does that mean I am owner?
exec('wget http://wordpress.org/latest.tar.gz');
exec('tar -xzvf latest.tar.gz');
Most likely, if run from apache, the user that apache is running as.
Whatever user runs PHP. Its either the web server's system user name, or the owner of the webroot (through suexec). If owned by the server, its likely nobody or www-data.
What matters most is what user PHP (server side) is running as. Try this to find out.
You can do echo shell_exec('whoami');
And that will output the name of the user. For me, it outputted apache
And yes, apache will own the files. For example, if you do something like this as root:
root#localhost# cp /home/user/foo /home/user/foo2
root#localhost# ls -l /home/user
-rw-rw-r-- 1 user user 232 Apr 12 12:00 foo
-rw-rw-r-- 1 root root 232 Apr 12 12:01 foo2

Categories