Running command-line application from PHP as specific user
One solution is using sudo(8)
:
exec('sudo -u myuser ls /');
You will, obviously, need to setup sudo(8)
to allow the user running your webserver to invoke it. Editing the sudoers file with visudo(8)
, you can use something like:
wwwuser ALL=/usr/bin/rhythmbox-client
To prevent Apache from being able to run other commands and only the rythymbox command.
How to run executable from PHP website as a specific Windows user?
I kept digging and found out that the only thing that works is a dedicated application pool.
- Create a new Application Pool under IIS
- Set username and password in
Advanced Settings > Identity > Custom account
- Set
Advanced Settings > Load User Profile
totrue
(this one is important) - Choose this pool under Basic Settings of a site,
-or- for a better security:
. 5.Move all command-relatied code to one section within your website, convert it to application and apply that Application Pool to it. Then you can restrict any public access to that part and safely call that functionality from the other parts of your site.
Important note (!):
If you're running PHP via FastCGI, you must set fastcgi.impersonate = 0
in php.ini
file.
Test batch file:
To test who is running the process you can save the following code to a *.bat
file and call it from PHP.
@echo off
SET now=%date% %time%
SET out=[%now%] %userdomain%\%username%
echo %out%
echo %out% > D:\hello.txt
::msg * "%out%"
if %username%=="SpecificUser" (
exit /B 100
) else (
exit /B 200
)
Replace SpecificUser
with your desired user name. Sometimes you'll see no output. The exit codes will help you then.
In case you can't see any output or exit code at all, this script will output the username to a text file. Replace D:\hello.txt
with your desired path.
PHP exec() command function for user other than PHP user
I figured it out. I'm sharing because this answer could be featured in the dictionary under "Non-Obvious Information"
Obviously the issue is that PHP (running under IIS) executes these commands as LOCAL\IUSR, which doesn't have admin permissions. I needed to reconfigure IIS so that it runs the site's application pool as my DOMAIN\SVC account, which has the proper permissions. However, this still didn't work.
I'm not exactly certain why, but the missing piece was an Application Pool setting called "Load User Profile", which needs to be set to true. After setting that it worked fine, though I couldn't find any documentation anywhere explaining why.
All steps to implement fix:
- In IIS Manager, select the server item "Application Pools", then right click on the pool used by your website, and select "Advanced Settings". In this list, change the following settings:
- Edit Identity, chose "Custom Account" and enter the
DOMAIN\SVC
credentials. This is documented here and here. - Set Load User Profile to
True
.- Note: if you encounter a "keyset does not exist" error, see this MS support article
- Edit Identity, chose "Custom Account" and enter the
- In IIS Manager, open the Authentication feature of your website. Right-click "Anonymous Authentication" and choose "Edit", then set it to "Application Pool Identity".
- In Windows Explorer, navigate to
C:\Windows
and open the properties dialog for theTemp
subdirectory. Under the Security tab, add R/W permissions for theDOMAIN\SVC
account toC:\Windows\Temp
- Note: this lets the service account access PHP temporary files
As a quick aside, the "Load User Profile" setting was only implemented in IIS 7.5+, so presumably this does not work for IIS 7.0 and older.
PHP: Executing Command Line Application That Prompts Users
That's what the 'yes' program is for. It dumps an endless stream of 'y\n' (or whatever you tell it to via arguments) to the program. It exists for this purpose (answering 'yes' to "do you want to continue" prompts).
shell_exec('yes | foo -arg1 -arg2 -arg3')
How to run a function in a PHP Class from Command Line (Symfony)
look at the constructor, this class uses dependencies that implement the EntityManagerInterface and UserPasswordHasherInterface interfaces, if you want to use the TestHashPassword class outside of the Symfony context, you should create instances of these dependencies.
However, you probably want to use Symfony DI container. Then let's create a console command, via:
php .\bin\console make:command test-hash-password
Next, place the hashPassword method call in the execute section:
<?php
namespace App\Command;
use App\TestHashPassword;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand(
name: 'test-hash-password',
description: 'Add a short description for your command',
)]
class TestHashPasswordCommand extends Command
{
public function __construct(
TestHashPassword $testHashPassword,
)
{
parent::__construct();
$this->testHashPassword = $testHashPassword;
}
protected function configure(): void
{
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$this->testHashPassword->hashPassword();
$io->success('The hashPassword method called successfully!');
return Command::SUCCESS;
}
}
Now you can execute your new command:
php .\bin\console test-hash-password
Different results running script from command line vs. PHP
Since the script doesn't begin with a shebang line, it's being executed using whatever shell is being used by the caller. That's /bin/sh
for PHP, but probably /bin/bash
for you.
This is probably changing whether the echo
command supports the -en
option to process escape sequences -- it works interactively, but not from PHP.
You should always begin scripts with #!/bin/bash
or #!/bin/sh
to make sure they use the shell you want.
And rather than echo
, use printf
, which has more consistent behavior.
#!/bin/bash
printf "GET / HTTP/1.1\nHost: www.betoglou.com\nConnection: keep-Alive\n\n" | time /test/openssl/bin/openssl s_client --connect origin.betoglou.com:443 --servername www.betoglou.com -ign_eof
How do you execute a method in a class from the command line
This will work:
php -r 'include "MyClass.php"; MyClass::foo();'
But I don't see any reasons do to that besides testing though.
Related Topics
Calculating Days of Week Given a Week Number
Remove All Elements from Array That Do Not Start With a Certain String
What Are PHP Nested Functions For
PHP Fatal Error Failed Opening Required File
How Safe Are Pdo Prepared Statements
PHP Sessions Timing Out Too Quickly
Get the Date of Next Monday, Tuesday, etc
Any Way to Return PHP 'Json_Encode' With Encode Utf-8 and Not Unicode
How to Get the Real Url After File_Get_Contents If Redirection Happens
Cannot Modify Header Information - Headers Already Sent By... Wordpress Issue
PHP Check If File Contains a String
Smtp Connect() Failed PHPmailer - PHP
How to Get the Sqlsrv Extension to Work With PHP, Since Mssql Is Deprecated
Pdo Error: " Sqlstate[Hy000]: General Error " When Updating Database