ログインとsu内部


10

Linuxでのユーザー権限の仕組みを理解しようとしています。カーネルが起動しinit、ルートとして起動しますよね?その後、Initは起動スクリプトを実行し、再度rootとしてgettyagetty)を実行します。Agettyはユーザー名を読み取って実行しますがlogin、それでもrootのままです。まだ何も面白くない。しかし、ログインは何をしますか?「ログインしようとする」以上のものを見つけることができませんでした。ログインでパスワードが一致すると(そして通常のユーザーとしてログインしようとすると)検出された場合、ユーザーIDをどのように変更しますか?そのためのシステムコールがあるはずだと思いましたが、それを見つけることができませんでした(多分、私は盲目なのでしょうか?)


また、についてsusu「setuid」ビットが設定されているため、実行すると、常にルートとして実行されます。しかし、通常のユーザーとしてログインするように指示すると、再びユーザーIDを変更する必要があります。同じ「マジック」がユーザーを変更する必要があるときsuloginいつ発生するかを正しく理解していますか?もしそうなら、なぜ2つの異なるプログラムがあるのですか?ログインを実行しているときに、その他の深刻なビジネスが発生していますか?

回答:


9

ログインプログラムが行うことにはいくつかの部分があります。ログインプログラムは、ログインしようとしているユーザーとの対話方法が異なります。次にいくつかの例を示します。

  • login:テキスト端末で入力を読み取ります
  • su:すでにログインしているユーザーによって呼び出され、コマンドライン引数からほとんどのデータを取得し、さらにターミナルから認証データ(パスワード)を取得します
  • gksu:に似てsuいますが、Xで認証データを読み取ります
  • rlogindrloginプロトコルを介してTCP接続を介して入力を取得します
  • sshdSSHプロトコルを介してTCP接続経由で入力を取得します
  • Xディスプレイマネージャー(xdm、gdm、kdmなど):に似てloginいますが、Xディスプレイで入力を読み取ります

これらのプログラムは同様の方法で動作します。

  1. 最初の部分は認証です。プログラムはユーザーから何らかの入力を読み取り、ユーザーがログインすることを許可されているかどうかを判断します。従来の方法は、ユーザー名とパスワードを読み取り、ユーザーがシステムのユーザーデータベースに記載されていることを確認することです。ユーザーが入力したパスワードはデータベース内のパスワードであること。しかし、他にも多くの可能性があります(ワンタイムパスワード、生体認証、認証転送など)。

  2. ユーザーのログインがどのアカウントで許可されていることが確認されると、ログインプログラムはユーザーの許可を確立します。たとえば、ユーザーがこのセッションで所属するグループなどです。

  3. ログインプログラムは、アカウントの制限をチェックする場合もあります。たとえば、ログイン時間やログインユーザーの最大数を強制したり、特定の接続で特定のユーザーを拒否したりできます。

  4. 最後に、ログインプログラムがユーザーのセッションを設定します。いくつかのサブステップがあります。

    1. プロセス許可を許可で決定されたものに設定します:ユーザー、グループ、制限、... このサブステップの簡単な例をここに示します(ユーザーとグループのみを処理します)。基本的な考え方は、ログインプログラムはこの時点ではまだrootとして実行されているため、最大の特権を持っているということです。最初にrootユーザー以外のすべての特権setuidを削除し、最後に最後の特権を削除するように呼び出します。
    2. おそらく、ユーザーのホームディレクトリをマウントしたり、「メールがあります」メッセージを表示したりします。
    3. ユーザーとしてプログラムを起動します。通常はユーザーのシェルです(for loginおよびsu、またはsshdコマンドが指定されていない場合。XディスプレイマネージャーがXセッションマネージャーまたはウィンドウマネージャーを呼び出します)。

今日のほとんどのuniceは、PAM(Pluggable Authentication Modules)を使用して、ログインサービスを管理する統一された方法を提供しています。PAMの機能は4つの部分に分かれています。「auth」には、認証(上記1)と承認(上記2)の両方が含まれます。「アカウント」と「セッション」は上記の3と4と同じです。また、ログインには使用されず、認証トークン(パスワードなど)を更新するために使用される「パスワード」もあります。


4

このシステムは、あなたがのようなものと呼ばれて探している呼び出すsetuidseteuid、あなたが変更しようとしているユーザの身元の変異体を正確に応じて裾の家族全員が実際にありますが。

setgidプロセスが実行されているグループを変更するような並列呼び出しもあります。


4

login必要に応じてroot権限を削除します。最初にroot権限のみを必要とする多くのプログラムは、rootとして起動し、必要なことを実行してから、通常のユーザーアカウントにドロップダウンするため、バイナリのバグを使用して誰かにアクセスすることを心配する必要がありません。ルートシェル。login当然のことながら特権は長く保持されますが、原則は同じです。

実際にルート権限を削除するのはかなり簡単です。POSIXはsetuid()setgid()ユーザーIDとグループIDをそれぞれ変更する定義と機能(rootから始めた場合は、実際と有効)。loginこれらの両方を呼び出すだけでなく、initgroups()追加のグループをセットアップします(これsetgidは、プライマリグループIDを設定するためだけなので)

当然、プロセスのUID / GIDの変更を実際に処理するのはカーネルです。Linuxカーネルシステムコールの実装を見つけるにはどうすればよいですか?syscallsについて多くを説明します。私のカーネルソースには私が持っています:

#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)

したがって、144と146は、私のマシンのこれらの関数のシステムコール番号です。


私はsuソースをチェックしてその機能を確認しませんでしたがexec()、同じ方法を使用して、シェルを実行する直前にroot権限もドロップするのではないかと思います

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.