web-dev-qa-db-ja.com

php exec()のsudo

契約がここに何があるかわかりません…

だから私はapplescriptを実行したい:Sudo osascript myscript.scpt

これは端末では正常に機能しますが、PHPのexec()で実行した場合は機能しません。何も起こりません。コンソールは言う

no tty present and no askpass program specified ; TTY=unknown ; …

調査を行ったところ、Sudoコマンドのパスワードが不足しているようです。これを回避するために、いくつかの異なる方法を試しました。

  • /etc/sudoers%admin ALL=(ALL) ALLと書く
  • およびproc_open()の代わりにexec()

どれも機能していないようで、結果としてCrAzYを駆り立てています!

基本的に、単純な端末コマンドを実行するためのPHPを取得する明確な方法はありますか?

編集:明確にするために、myscript.scptは、画面上のUIを変更する単純なappleScriptです(より大きなプロジェクトの場合)。理論的には、単にosascript myscript.scptで十分ですが、Sudoは何らかの理由で呼び出すのに必要です 一部 システムからの応答。 Sudoを何らかの方法で削除できる場合、このアクセス許可の問題は発生しないと思います。

41
pop850

パスワードなしのSudoをセットアップする必要があるようです。試してください:

%admin ALL=(ALL) NOPASSWD: osascript myscript.scpt

また、次の行(visudo経由の/ etc/sudoers内)がある場合はコメントアウトします。

Defaults    requiretty
17
tomit

まだこれが必要な場合。 〜./。sudopass/sudopass.secretなどのプレーンテキストファイルを、そこにrootパスワードを付けて書き込むことができます。ルートパスワードが「12345」だとしましょう。 〜./。sudopass/sudopass.secretを作成し、その内容として'12345'のみを使用します。

12345

そして、次のことを行います。

exec('Sudo -u root -S {{ your command }} < ~/.sudopass/sudopass.secret');

これは、制御された環境でのみ使用することを忘れないでください。

15
scabezas

次のようなvisudoを使用して、ユーザーとコマンドに特定のアクセスをもたらすことができると思います。

nobody ALL = NOPASSWD: /path/to/osascript myscript.scpt

およびphpの場合:

@exec("Sudo /path/to/osascript myscript.scpt ");

nobodyユーザーがApacheを実行していると仮定します。

9
Ezequiel Hdez.

php:bashコンソールが作成され、最初のスクリプトが実行されます。これにより、Sudoが2番目のスクリプトに呼び出されます。以下を参照してください。

$dev = $_GET['device'];
$cmd = '/bin/bash /home/www/start.bash '.$dev;
echo $cmd;
Shell_exec($cmd);
  1. /home/www/start.bash

    #!/bin/bash
    /usr/bin/Sudo /home/www/myMount.bash $1
    
  2. myMount.bash:

    #!/bin/bash
    function error_exit
    {
      echo "Wrong parameter" 1>&2
      exit 1
    }
    ..........
    

oc、root権限なしでrootレベルからスクリプトを実行して、/ etc/sudoers.d/mountファイルを作成および変更します。

www-data ALL=(ALL:ALL) NOPASSWD:/home/www/myMount.bash

chmodを忘れないでください:

Sudo chmod 0440 /etc/sudoers.d/mount
4
lisu

_Sudo visudo_コマンドを実行してから、-%Sudo ALL=(ALL:ALL)%Sudo ALL=(ALL:ALL) NOPASSWD: ALLに設定します。

1

同様の状況で、exec()バックエンドコマンドを試行し、Webサーバーエラーログでno tty present and no askpass program specifiedを取得しました。元の(悪い)コード:

$output = array();
$return_var = 0;
exec('Sudo my_command', $output, $return_var);

次のようなbashラッパーがこの問題を解決しました。

$output = array();
$return_var = 0;
exec('Sudo bash -c "my_command"', $output, $return_var);

これがすべての場合に機能するかどうかはわかりません。また、my_command部分に適切な引用/エスケープルールを適用してください。

0
Balage

最も安全な方法は、crontabを使用することです。つまり、すべてのコマンドをデータベース(mysqlテーブルなど)に保存し、cronジョブを作成してこれらのmysqlエントリを読み取り、exec()またはShell_exec()を介して実行します。詳細については、こちらをお読みください link .

          • killProcess.php
0

最近、PHPが実際のBashシェルを取得して対話できるようにするプロジェクトを公開しました。ここから入手できます。 https://github.com/merlinthemagic/MTS シェルにはpty(つまり、sshセッションで使用するのと同じ疑似端末デバイス)があり、必要に応じてシェルをルートとして取得できます。スクリプトを実行するのにルートが必要かどうかはわかりませんが、 。

ダウンロード後、次のコードを使用するだけです。

$Shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $Shell->exeCmd('/path/to/osascript myscript.scpt');
0
MerlinTheMagic