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
次のように通知されます。ls
openat
EACCES
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
が失敗します。この場合、エラー呼び出しはEPERM
(1: 操作は許可されません。)。プログラムはifconfig
次の場所で警告します。そのsetifflags
機能:
// ...
if (ioctl(s, SIOCSIFFLAGS, &ifreq) == -1)
err(EXIT_FAILURE, "SIOCSIFFLAGS");
// ...