カスタム PAM セッション内からユーザーを適切に認証する方法はありますか?
現在、外部トークンを使用してユーザーがログインできるようにする独自の PAM 認証モジュールを作成しています。このトークンは、ユーザーがモジュールを使用してログインする前に生成する必要があります。したがって、トークンが存在しない場合にはデフォルトの PAM 認証にフォールバックし、ユーザーが認証されるとすぐにコードを続行したいと思います。
これはどういうわけか可能ですか? 疑似コードでは、私のモジュールは次のようになります。
pam_sm_authenticate() {
if (first_login) {
code_copied_from_pam_unix_to_authenticate_user();
// do something else here?
} else {
custom_auth();
}
}
簡単な解決策として、Linux の pam_unix モジュールのコードを自分のモジュールにコピーしたところ、うまくいきました。ただし、これでは多くの追加ライブラリが必要になり、pam_unix が変更されない限り機能しないため、あまり満足のいくものではありません。セッション内で別の PAM セッションを開きたいのですが、うまくいきません。
答え1
コードにすべてのロジックを実行させないでください。最初に PAM とその構成を使用して、モジュールが最適な条件で実行されるようにします (つまり、pam_unix
のコードをコピーする必要はありません)。
まず、モジュール用の別の疑似コードを提案します。
pam_sm_authenticate() {
if (first_login) return PAM_CRED_INSUFFICIENT;
else custom_auth();
}
ここで私は考える最初のログイン認証情報が不十分なケースです。モジュールが失敗しているのは、ユーザーを完全に認証するために必要なものがすべて揃っていないためだと PAM に伝えています。ここで、モジュールの名前が であると仮定するとmy_module
、考えられる構成は次のようになります。
auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1] pam_unix.so
auth sufficient my_module.so
auth requisite pam_deny.so
詳細は次のとおりです。
まず、リクエストは を通過します
my_module
。ここではいくつかの可能性があります:- 最初のログイン: モジュールが返されました
PAM_CRED_INSUFFICIENT
。このケースはつかまったPAM(経由cred_insufficient
)によって、その場合、チェーンを成功(ok
)としてマークするように設定されますが、続けて。 - これは最初のログインではありませんでした。ログイン
custom_auth()
に成功しました ( が返されましたPAM_SUCCESS
)。この場合、チェーンを終了しました (done
)。アクセスを許可。 - これは最初のログインではなく、
custom_auth()
うまくいきませんでした (PAM_AUTH_ERR
または他の種類の内部エラー)。この場合、次の 2 行 (default=2
) をスキップします。チェーンはすぐに に進みpam_deny
、常に失敗します。アクセスが拒否されました。
- 最初のログイン: モジュールが返されました
最初のシナリオでは、チェーンは まで続きます
pam_unix
。ここでは 2 つの可能性があります。- UNIX認証が成功しました。これにより、チェーンは成功(
ok
)とマークされ、次のモジュールに進む。 - UNIX 認証に失敗しました。次のモジュールはスキップされ (
default=1
)、チェーンは で終了しますpam_deny
。アクセスが拒否されました。
- UNIX認証が成功しました。これにより、チェーンは成功(
3 行目に到達した場合、 が最初
my_module
に終了し、 が成功したことを意味します。モジュールはとして再度 ( )呼び出されます。ここでも 2 つの可能性があります。PAM_CRED_INSUFFICIENT
pam_unix
// do something else here?
sufficient
- 今回は、モジュールは成功しました:アクセスを許可。
- モジュールは再度失敗しますが、資格情報の不足とは別の理由です。アクセスが拒否されました。
カスタムコードを実行することもできますUNIX認証後失敗した場合でも、実行を継続します。そのためには、2 行目を次のように変更します。
auth [success=ok default=bad] pam_unix.so
これにより、チェーンはmy_module
必ずもう一度実行されますが、チェーンは次のようにマークされます。失敗したモジュールがここで成功したとしても、チェーンは失敗します。
モジュールにチェーン内で何回呼び出されたかを認識させ、最初の呼び出しとmy_module
2 番目の呼び出しを区別することもできます。これは引数を使用して簡単に行うことができます。
auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1] pam_unix.so
auth sufficient my_module.so second_time
auth requisite pam_deny.so
ここで、2回目の呼び出しでは引数(およびを介して)pam_sm_authenticate
が渡され、argv
argc
見つける実行時にチェーン内のモジュール。もちろん、firstLogin
このような区別を行うには条件で十分です。