有沒有辦法在自訂 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
。這裡有兩種可能性:- UNIX 身份驗證成功。這標誌著該鏈成功 (
ok
) 且繼續下一個模組。 - UNIX 身份驗證失敗。跳過下一個模組 (
default=1
),鏈以 結束pam_deny
:拒絕訪問。
- UNIX 身份驗證成功。這標誌著該鏈成功 (
如果到了第三行,就表示第一次
my_module
結束了,成功了。您的模組再次被呼叫 ( ) 作為。又是兩種可能:PAM_CRED_INSUFFICIENT
pam_unix
// do something else here?
sufficient
- 這次,您的模組成功了:授予存取權限。
- 該模組再次失敗,但除了憑證不足之外還有另一個原因:拒絕訪問。
您可能還想執行自訂程式碼UNIX 驗證後,即使失敗了。為此,請將第二行更改為:
auth [success=ok default=bad] pam_unix.so
my_module
無論如何,這都會使該鏈再經歷一次,但該鏈將被標記為失敗的。即使您的模組最終在這裡成功,該鏈也會失敗。
您可能還想讓您的模組知道我們在鏈中調用了它多少次:區分第一次調用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 second_time
auth requisite pam_deny.so
在這裡,第二次呼叫pam_sm_authenticate
將傳遞一個參數(通過argv
和argc
),這應該對您有幫助定位運行時鏈中的模組。當然,你的firstLogin
條件應該足以做出這樣的區分。