web-dev-qa-db-ja.com

プログラムがsudoで実行されていることを通知できますか?

「Sudo」で実行されている場合、動作が異なるプログラムがあります。 sudoで実行されたかどうかを確認する方法はありますか?

更新:誰かがなぜこれをしたいのかと尋ねました。この場合、MacPortsを使用するMacでは、特定のコマンドをカットアンドペーストするように指示する出力があります。 MacPortsコマンドが「Sudo」で実行された場合、サンプルコマンドにSudoを含める必要があります。

$ Sudo port selfupdate 
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.2.1 installed,
MacPorts base version 2.2.1 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

^^^^^^^^^ it would be really sweet if it output "Sudo port upgrade outdated" instead.  It would be even better if it just did it for you :-)
28
TomOnTime

はい、プログラムがSudoで実行されている場合、4つの環境変数が設定されています。

$ Sudo env |grep Sudo
SUDO_COMMAND=/usr/bin/env
Sudo_USER=tal
Sudo_UID=501
Sudo_GID=20

これらは設定するだけで偽造できることに注意してください。重要なものを信頼しないでください。

例:このプログラムでは、他のプログラムを実行するようにユーザーに指示する必要があります。現在の1つがSudoで実行されていた場合、もう1つも同様です。

#!/bin/bash

echo 'Thank you for running me.'

if [[ $(id -u) == 0 ]]; then
  if [[ -z "$Sudo_COMMAND" ]]; then
    echo 'Please now run: next_command'
  else
    echo 'Please now run: Sudo next_command'
  fi
else  echo 'Error: Sadly you need to run me as root.'
  exit 1
fi

ルートとして実行されていることを最初に証明できる場合にのみ、Sudo_ *変数をテストすることに注意してください。それでも、それはいくつかの役立つテキストを変更するためにそれを使用するだけです。

49
TomOnTime

これは直接質問に答えるものではありませんが、ここで正しい質問がされているとは思いません。質問者は、特定の権限があるかどうかにかかわらず、おそらく異なる動作をするプログラムを望んでいるように見えますが、私はSudoをチェックすることがその方法ではないと主張します。第一に、多くのシステムは「Sudo」を実装していない可能性があり、Linuxや多くのUnixでは必ずしも必要ではありません。

たとえば、ユーザーがすでにrootとしてログインし、Sudoを無意味にしたり、システムにroot以外のユーザーがいて、プログラムが実行したい管理タスクを実行する機能をまだ持っている可能性があります。最後に、おそらくシステムにはルートまたはSudoがまったくなく、代わりに、異なる機能を持つ必須のアクセス制御システムを使用し、すべてのスーパーユーザーをSudoにキャッチしません。または、ユーザーがsudoedされる可能性がありますが、セキュリティ上の理由により、自分のアカウントよりもアクセス許可が少ないアカウントにアクセスします(アクセス許可を上げるのではなく、削除するためにRAMディスクにのみ書き込むことができる一時的な非特権ユーザーで信頼できないコードを実行することがよくあります)。 Sudoやrootの存在などの特定の権限モデルを想定すること、またはsudoedユーザーが特定の権限を持っていると想定することは、全体的に悪い考えです。

操作を実行する権限があるかどうかを確認したい場合は、通常、単純に試行して実行することをお勧めします。失敗した場合、またはすべてが失敗するか、すべて成功する必要がある多段階操作である場合は、errnoで権限の問題を確認します。 POSIX access 関数などの関数で操作が機能するかどうかを確認できます(権限がアクティブに変更されている場合は、ここで起こり得る競合状態に注意してください)

さらに、Sudoの背後にある実際のユーザーを知る必要がある場合は、 getlogin 関数を使用できます。これは、基礎となる端末とのインタラクティブセッションで機能し、たとえば、監査用のコマンドを「実際に」実行しているユーザーを見つけたり、ログを保存する実際のユーザーのホームディレクトリを見つけたりします。

最後に、本当に必要なのは、ユーザーがrootアクセス権を持っているかどうかを調べることです(それでも悪い考えですが、実装固有ではありません)。 getuid を使用して確認できます。 uidが0の場合はrootになります。

11
Vality

使用できるメカニズムは2つあります。

  • 環境変数のチェックは、どちらの方法でも偽造できますが、最も簡単です。 growisofsはSudoで実行したくないので、使用するスクリプトでSudo変数の設定を解除します。逆に偽造することができます。 (Sudo変数は、atおよびbatchコマンドで実行されるスクリプトの環境にも組み込まれます。)
  • Sudoで実行しているかどうかを確認する別の方法は、親プロセスからプロセスリストを調べてSudoを探すことです。この方法でSudoの下で実行していたことを隠すのは難しいでしょうが、より複雑です。 Sudoの下で実行していることを偽ることはまだ可能です。

適切なユーザーとして実行しているかどうかを確認するのがより一般的です。これを行うには、idコマンドを使用できます。 TomOnTimeのスクリプトはidコマンドを使用して、次のコマンドを実行するためにSudoが必要かどうかを判断します。

7
BillThor

有効なユーザーIDと実際のユーザーIDを比較できます。

これは、厳密にundo Sudoを実行している(setuidされている可能性もあります)ことを意味するものではありませんが、プログラムがユーザーが予期するよりも多くの権限を持っていることを示しています。 (たとえば、通常はそのような権限なしで実行されますが、インストール中に実行したり、更新をインストールしたりする必要があるプログラムで。これを使用して、警告に関するフィードバックを提供できます)。

2
blabla999

次のようにして、実効UID(EUID)変数を確認できます。

if [[ $EUID -eq 0 ]]; then
    echo "running as root"
else
    echo "not running as root"
fi
2
Eliran Malka