sudoは、すべての権限を持つsudoerだけがコマンドを実行できるかどうかをどのように決定しますか?

sudoは、すべての権限を持つsudoerだけがコマンドを実行できるかどうかをどのように決定しますか?

sudoがインストールされているDebianシステムでは、デフォルトのユーザーが実行できますが、バイナリは同じ権限を持っているため、なぜ実行できlsないのか疑問に思います。ifconfig

-rwxr-xr-x 1 root root 114032 Jan 26  2013 /bin/ls
-rwxr-xr-x 1 root root 72296 Sep  7  2012 /sbin/ifconfig

その場合は、コマンドを実行できる人と実行できない人をシステムに知らせる一種のデータベースやポリシーがあると思います。しかし、どこで見つけることができますか?不可能です。/etc/sudoersこれは、誰がroot sudoerであり、誰が次のものではないかを定義していないためです。

%admin  ALL=(ALL)   ALL
john ALL=/usr/sbin/useradd, /usr/sbin/userdel, /usr/bin/passwd

これでjohn実行できません/sbin/ifconfig。しかし、システムはそれが許されないことをどうやって知ることができますか?

答え1

sudoこの小さな違いにもかかわらず、制限はカーネルに近いです。誰もがプログラムを実行する権利がありますが、/sbin/ifconfigこれがプログラムが実行されるという意味ではありません。一般ユーザー権限でタスクを完了するのに十分な権限が必要です。

デフォルトでは、UNIX権限設定を使用すると、次の権限があります。/sbin/ifconfig実行可能なコードを含むプロセスを生成します。。実際には、彼らが後でどのようにls行動ifconfigしても、彼らのプロセスははいそんなことが起こりました。ただし、ifconfigこれを実行しているユーザーに十分な権限が付与されていないため、早期に終了します。 Frank Thomasのコメントを引用すると、次のようになります。

[それはできません]ネットワークカードオブジェクトをつかむ

メモ:ifconfig --help実際には許可なく実行することもできます。この操作にはネットワークカードが必要ないため失敗し、root権限は必要ありません。

これで、低い権限で拒否されるタスクについてより具体的に知りたい場合は、次のことを試すことができifconfigますstrace。以下はの例ですls

strace - システムコールとシグナルトラッキング

これエラーコード許可拒否値は13(EACCES)です。以下を使用して、straceどのシステムコールがトリガーされているかを確認できますEACCES

$ strace ls ~ 2>&1 | grep EACCES
# No output, I can read my home directory just fine.
$ strace ls /root 2>&1 | grep EACCES
openat(AT_FDCWD, "/root", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 EACCES (Permission denied)

openatそこからシステムコールが失敗したことがわかります。実際、現在のユーザーとして、私はそのディレクトリを読み取る権限がないので、カーネルが関連/root情報lsを取得しようとしたときに失敗したことを認識して返すと、/root次のように通知されます。lsopenatEACCES

ls: ディレクトリを開けません。 /root: 権限が拒否されました。

システムコールが失敗したときにユーザーに通知するのはプログラムによって異なります。たとえば、Cでは次のようになります。

if((rootdir = opendir("/root")) == NULL){
    perror("myprogram");
    exit(1);
}

権限が低い状況では、次の結果が発生します。

$ ./myprogram
myprogram: Permission denied

これで、ユーザーとして実行したときにどのシステムコールが拒否されたかをstrace /sbin/ifconfig確認できます。ifconfig以下は、ワイヤレスインターフェイスをオフにしようとする例です。

$ strace ifconfig wlan0 down 2>&1 | grep EPERM
ioctl(4, SIOCSIFFLAGS, {ifr_name="wlan0", ???}) = -1 EPERM (Operation not permitted)

ご覧のとおり、システムコールioctlが失敗します。この場合、エラー呼び出しはEPERM1: 操作は許可されません。)。プログラムはifconfig次の場所で警告します。そのsetifflags機能:

// ...
if (ioctl(s, SIOCSIFFLAGS, &ifreq) == -1)
    err(EXIT_FAILURE, "SIOCSIFFLAGS");
// ...

関連情報