I need to detect if php is running as nobody. How do I do this?
Are there any other names for "nobody"? "apache"? Any others?
<?php echo exec('whoami'); ?>
If available you can probe the current user account with posix_geteuid and then get the user name with posix_getpwuid.
$username = posix_getpwuid(posix_geteuid())['name'];
If you are running in safe mode however (which is often the case when exec is disabled), then it's unlikely that your PHP process is running under anything but the default www-data or apache account.
Kind of backward way, but without exec/system:
file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
If you create a file, the owner will be the PHP user.
This could also likely be run with any of the temporary file functions such as tempnam(), which creates a random file in the temporary directory and returns the name of that file. If there are issues due to something like the permissions, open_basedir or safe mode that prevent writing a file, typically, the temp directory will still be allowed.
More details would be useful, but assuming it's a linux system, and assuming php is running under apache, it will run as what ever user apache runs as.
An easy way to check ( again, assuming some unix like environment ) is to create a php file with:
<?php
print shell_exec( 'whoami' );
?>
which will give you the user.
For my AWS instance, I am getting apache as output when I run this script.
You can try using backticks like this:
echo `whoami`;
I would use:
lsof -i
lsof -i | less
lsof -i | grep :http
You can type any of these in your ssh command line and you will see which user is listening to each service.
You can also check this file:
more /etc/apache2/envvars
and look for these lines:
export APACHE_RUN_USER=user-name
export APACHE_RUN_GROUP=group-name
To filter out envvars file data, you can use grep:
more /etc/apache2/envvars | grep APACHE_RUN_
Straight from the shell you can run:
php -r "echo exec('whoami');"
exec('whoami') will do this
<?php
echo exec('whoami');
?>
In my setup I want to check if the current process has permission to create folders, subfolders and files before I begin a process and suggest a solution if it looks like I can't. I wanted to run stat(<file>) on various things to ensure the permissions match those of the running process (I'm using php-fpm so it varies depending on the pool).
The posix based solution Mario gave above, seems perfect, however it seems the posix extension is --disabled so I couldn't do the above and as I want to compare the results with the response from running stat() running whoami in a separate shell isn't helpful either (I need the uid and gid not the username).
However I found a useful hint, I could stat(/proc/self) and stat(/proc/self/attr) and see the uid and gid of the file.
Hope that helps someone else
Proposal
A tad late, but even though the following is a work-around, it solves the requirement as this works just fine:
<?
function get_sys_usr()
{
$unique_name = uniqid(); // not-so-unique id
$native_path = "./temp/$unique_name.php";
$public_path = "http://example.com/temp/$unique_name.php";
$php_content = "<? echo get_current_user(); ?>";
$process_usr = "apache"; // fall-back
if (is_readable("./temp") && is_writable("./temp"))
{
file_put_contents($native_path,$php_content);
$process_usr = trim(file_get_contents($public_path));
unlink($native_path);
}
return $process_usr;
}
echo get_sys_usr(); // www-data
?>
Description
The code-highlighting above is not accurate, please copy & paste in your favorite editor and view as PHP code, or save and test it yourself.
As you probably know, get_current_user() returns the owner of the "current running script" - so if you did not "chown" a script on the server to the web-server-user it will most probably be "nobody", or if the developer-user exists on the same OS, it will rather display that username.
To work around this, we create a file with the current running process. If you just require() this into the current running script, it will return the same as the parent-script as mentioned; so, we need to run it as a separate request to take effect.
Process-flow
In order to make this effective, consider running a design pattern that incorporates "runtime-mode", so when the server is in "development-mode or test-mode" then only it could run this function and save its output somewhere in an include, -or just plain text or database, or whichever.
Of course you can change some particulars of the code above as you wish to make it more dynamic, but the logic is as follows:
define a unique reference to limit interference with other users
define a local file-path for writing a temporary file
define a public url/path to run this file in its own process
write the temporary php file that outputs the script owner name
get the output of this script by making a request to it
delete the file as it is no longer needed - or leave it if you want
return the output of the request as return-value of the function
add the file info.php to the following directory - your default http/apache directory - normally /var/www/html
with the following contents
<?php
phpinfo();
?>
Then httpd/apache restart
the go to your default html directory
http://enter.server.here/info.php
would deliver the whole php pedigree!
You can use these commands :
<? system('whoami');?>
or
<? passthru('whoami');?>
or
<? print exec('whoami');?>
or
<? print shell_exec('whoami');?>
Be aware, the get_current_user() returns the name of the owner of the current PHP script !
I usually use
<?php echo get_current_user(); ?>
I will be glad if it helped you
$_SERVER["USER"]
$_SERVER["USERNAME"]
<?php phpinfo(); ?>
save as info.php and
open info.php in your browser
ctrl+f then type any of these:
APACHE_RUN_USER
APACHE_RUN_GROUP
user/group
you can see the user and the group apache is running as.
$user = $_SERVER['REMOTE_USER'];
http://php.net/manual/en/reserved.variables.server.php
Authenticated user
Related
I am trying to programmatically append an RSA public key to the authorized_keys file through a website and haven't been able to make any solutions I found work. I have tried using PHP's file_put_contents() function but I run into a permission denied error, and I have a python script that works, but I cannot seem to get PHP to execute it with either the exec() command or shell_exec(). Here's the relevant PHP code:
if(#$_POST['action']=='submit'){
$key = $_POST['key_field'];
//file_put_contents("/home/biosproject/.ssh/authorized_keys", $key, FILE_APPEND);
$test = "/usr/bin/python savetofile.py \"".$key."\"";
$tmp = shell_exec($test);
}
I'm aware that I need to sanitize the input but the site is currently in development so I'm just testing it like this in the meantime. Right now I'm using XAMPP which runs Apache. Is there something I'm missing or could try? For the PHP exec/shell_exec, I have tried using the full pathnames for all parts of the command, but nothing has worked yet. The python script is as follows:
#!usr/bin/python
import sys
key = sys.argv[1]
with open("/home/biosproject/.ssh/authorized_keys","a") as append:
diditwork = append.write(key)
print key
As I mentioned before, this script is functional, but I can't call it from the PHP script.
EDIT:
My authorized_keys file looks like so: -rw-rw-rw- 1 biosproject www-data 1200 Apr 15 13:17 /home/biosproject/.ssh/authorized_keys
UPDATE:
I fixed the problem by bypassing permissions using a cron job that appends the necessary information from a database entry instead. Works great now!
The Python script won't help you here - it's a permissions issue with the /home/biosproject/.ssh/authorized_keys file, i.e. Apache doesn't have permission to modify it, and nor will any process it spawns, which would include your Python script.
Simplest fix would be to change the file permissions so it's writable by Apache. Assuming apache runs as group www-data, do...
sudo chgrp www-data /home/biosproject/.ssh/authorized_keys
sudo chmod g+w /home/biosproject/.ssh/authorized_keys
...although I forget if ssh complains if authorized_keys is set to g+w.
Update
It occurs to me that www-data will also need +x access to all parent directories of /home/biosproject/.ssh/authorized_keys to be able to change it, although I'm pretty sure that ssh will complain if you change the .ssh directory permissions in this way.
You'll either have to run apache with the same UID as the owner of the /home/biosproject/.ssh directory, or use a setuid script to make the changes.
Explanation about my inline code:
$text = "nice text to append :P";
// open a file handler with a+ flag that means "open file for append and if it does not exist, create it"
$fo = fopen("filename.ext", "a+");
// append $text to file handler with a \n at the end
fwrite($fo, $text . PHP_EOL);
Ok I need to run my Apache web server as root. For this I typed whoami; in terminal. It gives me output: root. But when I check my apache server running as a root user or not by executing following php-script: < ?php echo whoami; ?> It gives me output: nobody. So any suggestions to execute/login as a root user in apache??
I would suggest creating an external PHP file on your server that would handle everything related with this extension. And then, you could call this script with shell_exec in combination with sudo.
This way, you could put your webserver user in your sudoers file and let it run php-cli as root.
Then, in your script you could simply use:
$output = shell_exec("sudo /bin/php /yourscript.php");
This would be a much more secure solution than running Apache as root, which in my opinion, is a verry bad idea, even if you know what you are doing.
If you know what you are doing, look at the file /etc/apache2/envvars :
You can customize these variables
export APACHE_RUN_USER=root
export APACHE_RUN_GROUP=root
I echo the concerns running the apache process as root. Its just a bad idea.
Thats why I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('php /var/scripts/test.php');
//the return will be a string containing the return of the script
echo $return1;
I have a multithreaded cli downloader for ubuntu called Aria2c.
I've been trying to get a php script to run aria2c and download a file using shell_exec, but i can't seem to get it to work. Ultimately I plan to have an input box on a page where I can enter a link and aria would download it.
Here's the code I've come up with (for now im inputting the link manually):
<?php $dl = shell_exec('aria2c -d /home/user/ www.downloadlink.com'); ?>
Note that the aria2c command I specified works well in the shell; and the directory I'm attempting to download to is set to '777'.
I'm baffled as to why it's not working, any ideas?
PS: I prefer to use aria rather than the alternatives because it is multithreaded and it supports cookies.
Check if PHP is running in safe_mode. shell_exec won't work if safe_mode is on.
EDIT: aria2c was not referenced with a full path. Referencing it like this: shell_exec('/path/to/aria2c -d /home/user/ www.downloadlink.com') works.
I'll make the assumption that you are running PHP through a web server. In such case, it's very unlikely that the web server has permission to write into your user's home directory: Apache runs as daemon with the credentials of a limited user. Also, the PATH env variable in Apache is not necessarily the same as your user's PATH. Last but not least, you don't check the return value or the script output.
Try something like this:
<?php
exec('/path/to/aria2c -d /tmp www.downloadlink.com', $output, $return_var);
var_dump($output, $return_var);
?>
You can get the full path for aria2c with:
which aria2c
I am looking for ways to setup a basic site quickly.
I have a basic site which works with a databasem, templates, css, js and so on.
No I want to be able to quickly set up a site. What shoudld happen when i start the script is:
ask for some variables
on submit:
create a folder in the webroot
copy the standard site to that map
create a database based on a default db
add the new site to my vhost file
restart apache
add the new site to my host file
start de basic site in a browser.
What is the best way to create this script? How can I accomplish this?
Here's a complete (untested) hack that does about what you said. If you're comfortable in php then use that. Pseudo script:
#!/usr/bin/env php
<?php
echo "Site setup v0.0\n";
if($argc != 2){
echo "Usage:\n script sitename\n";
}
//set vars
$sitename = $argv[1];
$src_folder = "/path/to/some/folder";
$template_db ="template_site";
//copy files
`mkdir $sitename`;
`cp -R $src_folder $sitename`;
//copy template db
$dblink = mysql_connect("localhost");
if(!mysql_query($dblink, "CREATE DATABASE site_$sitename; USE site_$sitename;"))exit(-1);
$r = mysql_query($dblink, "SHOW TABLES FROM $template_db");
while($row = mysql_fetch_array($r)){
$table = $row[0];
mysql_query($dblink, "CREATE TABLE $table AS SELECT $template_db.$table");
}
//conf and restart apache
$f = fopen("httpd.conf","a");//open for append
fwrite("<VirtualHost $sitename> bla bla </VirtualHost>");
fclose($f);
`sudo apachectl -k restart`; //you'll be asked for a password here
//open in browser
`open http://$sitename/`; //on mac anyway...
?>
Make the file executable with
chmod +x filename
Remember that to run scripts in the current folder you need to add ./. Like
./scriptname sitename
Also note the slanted quotes ` <- They start a shell command. The first line is called a shebang-line (yes like that old 80s band, or what was it..) and tells a shell what to use to execute the file. (Env is a utility program that kinda finds other programs, in this case php. Good if you want to run the script in systems where php has different install locations.)
Also please note that this script is just pseudo codeāit does not work! Don't run it before modifying it!
This is something you have to do on the server so you can use any language you prefer. It's just about copying files, append text to files and execute some shell commands.
Well, it depends on what OS you are using, if you use Linux you can create simple script to do this, it basicly should contain a sequence of commands to set this up.
#!/bin/sh
mkdir /var/www/sitename
cp -au /var/www/skeleton/* /var/www/newfolder
etcetera.
You can then launch your script by running it from command line with some parameters
./initiatesite.sh newsite.com databasename addwhateverparameteryouwant here.
More info on passing parameters to a shell script: http://osr600doc.sco.com/en/SHL_automate/_Passing_to_shell_script.html
You can write a shell script that basically accomplishes all of that.
So I guess you would have a web front end handled by php which takes some parameters, and have that php script invoke a shell script (via system call) on your server to set up your db, copy files, append some lines to vhost config, etc
If this is not for your own use but for clients, I would take extra care to make sure all input is untainted and secure first.
You can't do that in PHP unless you run PHP as root (bad idea).
Think about what you want to do specifically and how you would do it. Starting the site in a browser is a user-specific desktop action, restarting the server is a root action as is all the copying/editing/moving stuff.
Maybe a proper installer would be more suited towards what you're trying to accomplish. It sounds like you're working with Windows -- do you only want to provide an installation for Windows? For Linux you'd need a shell script, for example.
The best way to write this would be as a command line script, which you can write in PHP if you want. Use the $argv variable to get an array of the command line variables. Make sure that this PHP file is NOT web accessible.
Also, I would use SVN to do a export to the folder for the new site. This will ensure that you have the most up to date code and that it's a clean copy.
I'm on a foreign linux system and need to determine the user that apache runs on (and so does php).
The aim:
I need to get the owner of the script (this is no problem as I can use SplFileInfo) and compare it to the owner of the apache process.
I'm open to any alternative proposals.
Regards,
Mario
Edit:
Additional info:
The script is a thumbnail generator, that uses an XML file to generate thumbs from larger images. The script needs to create folders and write files. As I cannot influence the php configuration and I do not have any shell access, this has to be done very silently.
The creation process stopps via exception and sends a mail on failue. As most of php's function cannot throw exceptions on failue, I need some manual checks to determine the environment I'm in. Therefore I need the apache user to compare it to some directory or fileowner.
You can call the php exec function to execute whoami:
<?php echo exec('whoami'); ?>
see posix_getuid() and posix_getpwuid()
Some complicated answers here.
This works for me:
$user = getenv('APACHE_RUN_USER');
Not sure if this is just a new thing that been added to apache since this question was asked but it's definitely there now.
phpinfo will dump a lot of system information. For apache2 installs, there is a section that displays the apache user and group ids. Try creating a php script that just has one line, a call to phpinfo(), and open it in your web browser.
Some php script must be run on apache user (cli), whoami is not appropriate in that case.
Here is my solution :
$output = exec('apachectl -S 2>/dev/null | grep User');
$apacheUser = preg_match('/name="([^"]+)"/', $output, $match) ? $match[1] : 'www-data';