$output = shell_exec('echo "php '.$realFile.'" | at '.$targTime.' '.$targDate.' 2>&1');
print $output;
Can someone please help me figure out why the above line isn't doing what it's supposed to be doing? The idea is for it to create an 'at' job that will execute a php script. If I switch to the user apache(which will ideally control the at function when the php file is complete) I can run
echo "php $realFile.php" | at 00:00 05/30/17
and it'll do EXACTLY what I want. The problem is in the above snippet from my php file it will not create the at job correctly. when I do a at -c job# on both of them the job made from my file is about a 3rd the length missing the User info and everything. It basically starts at PATH= and goes down. Doesn't include HOSTNAME=, SHELL=, SSH_CLIENT=, SSH_TTY=, USER=. I assume it needs most of this info to run correctly. The end output (below)is always the same though it just doesn't have any of the top part for some reason. Let me know if you need more info. I didn't want to paste all of my code here as it contains job specific information.
${SHELL:-/bin/sh} << 'marcinDELIMITER0e4bb3e8'
php "$realFile".php
marcinDELIMITER0e4bb3e8
It doesn't seem to be a permission issue because I can su to apache and run the exact command needed. The folder the files are located in are also owned by apache. I've also resulted to giving each file I try to run 777 or 755 permissions through chmod so I don't think that's the issue.
I figured out a coupe ways around it a while back. The way I'm using right now is an ssh2 connect to my own server as root and creating it that way. No compromise as you have to enter the password manually each time. Really bad work around. The main issue is that apache doesn't have the correct permissions to do everything needed for the AT job so someone figuring that out would be awesome. Another option I found on a random webpage would be to use sudo through the php script, but basically the same minus having to reconnect to your own server. Any other options would be appreciated.
Reading the manual and logs would be a good place to start. In particular:
The value of the SHELL environment variable at the time of at invocation will determine which shell is used to execute the at job commands. If SHELL is unset when at is invoked, the user’s login shell will be used; otherwise, if SHELL is set when at is invoked, it must contain the path of a shell interpreter executable that will be used to run the commands at the specified time.
Other things to check are that the user is included in at.allow, SELinux is disabled and the webserver is not running chrrot.
Is it possible to include global $_lib, $_SETUP; in crontab?
I have a cronjob writting in php file in internet directory (/internet/mycrontab.php), but seem like the crontab throws error when I using $_Lib like in $_lib['db']->db_fetch_object($query).
The $_Lib working fine if I enter the url directly in browser www.myweb.dom/internet/mycrontab.php, and the crontab also working fine if I remove the $_Lib like in $_lib['db']->db_fetch_object($query) by using hardcode sysntax (primary).
If it is possible to include global $_lib, $_SETUP;, how do I correctly do that?
Many thanks for the help.
The problem is that the crontab environment and your web app environment are different things.
The cronjob is run by php-cli while the app is run by apache (or NGINX, whatever) php module.
You should probably evaluate to include your library into the crontab file.
include "/path/to/your/library.php";
$_lib = "whatever";
$_SETUP = "whatever";
Without having a proper look at the code that's the best I can suggest.
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
I want to make a script that would run something in screen on root user. This has to be done through php system() function therefore I need to find out way to sudo to root and pass a password, all using PHP.
If you really need to sudo from PHP (not recommended), it's best to only allow specific commands and not require password for them.
For example, if PHP is running as the apache user, and you need to run /usr/bin/myapp, you could add the following to /etc/sudoers (or wherever sudoers is):
apache ALL = (root) NOPASSWD:NOEXEC: /usr/bin/myapp
This means that user apache can run /usr/bin/myapp as root without password, but the app can't execute anything else.
I'm sure there must be a better way to do whatever it is you're trying to accomplish than whatever mechanism you're trying to create.
If you simply want to write messages from a php script to a single screen session somewhere, try this:
In php
Open a file with append-write access:
$handle = fopen("/var/log/from_php", "wb");
Write to your file:
fwrite($handle, "Sold another unit to " . $customer . "\n");
In your screen session
tail -F /var/log/from_php
If you can't just run tail in a screen session, you can use the write(1) utility to write messages to different terminals. See write(1) and mesg(1) for details on this mechanism. (I don't like it as much as the logfile approach, because that is durable and can be searched later. But I don't know exactly what you're trying to accomplish, so this is another option that might work better than tail -F on a log file.)
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';