在 PAM 會話/PAM 會話中對 PAM 會話中的使用者進行外部身份驗證
有沒有辦法在自定義 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 會話,但沒有讓它工作。
不要讓您的程式碼執行所有邏輯:首先使用 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
: access denied結尾。如果到了第三行,就說明第一次就
my_module
結束了,那就成功了。您的模組再次被呼叫 ( ) 為. 又是兩種可能:PAM_CRED_INSUFFICIENT``pam_unix``// do something else here?``sufficient
- 這一次,你的模組成功了:訪問被授予。
- 該模組再次失敗,但另一個原因不是憑據不足:訪問被拒絕。
您可能還想在 UNIX 身份驗證之後執行自定義程式碼,即使它失敗了。為此,請將第二行更改為:
auth [success=ok default=bad] pam_unix.so
my_module
無論如何,這將使鏈條再次經歷一次,但鏈條將被標記為failed。即使您的模組最終在這裡成功,鏈也會失敗。你可能還想讓你的模組知道我們在一個鏈中呼叫了多少次:區分第一個呼叫和
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
andargc
),它可以幫助您在執行時在鏈中*定位您的模組。*當然,你的firstLogin
條件應該足以做出這樣的區分。