接前一篇文章:PAM从入门到精通(六)
本文参考:
《The Linux-PAM Application Developers' Guide》
先再来重温一下PAM系统架构:
更加形象的形式:
五、主要函数详解
5. pam_strerror
概述:
描述PAM错误代码的字符串。
详细描述:
pam_strerror函数返回一个指向字符串的指针,该字符串描述参数errnum中传递的错误代码,可能使用当前区域设置的LC_MESSAGES部分来选择适当的语言。应用程序不得修改此字符串。任何库函数都不会修改此字符串。
函数声明:
返回值:
此函数始终返回一个指向字符串的指针。
实例:
SDDM中的代码
参见SDDM包源码目录src/helper/backend/PamHandle.cpp中的PamHandle::getItem函数。
const void* PamHandle::getItem(int item_type) {
const void *item;
m_result = pam_get_item(m_handle, item_type, &item);
if (m_result != PAM_SUCCESS) {
qWarning() << "[PAM] getItem:" << pam_strerror(m_handle, m_result);
}
return item;
}
由于这个函数比较简单,捎带手直接给出其实现,而无需过多解析。其在PAM源码根目录下的libpam/pam_strerror.c中,代码如下:
const char *pam_strerror(pam_handle_t *pamh UNUSED, int errnum)
{
switch (errnum) {
case PAM_SUCCESS:
return _("Success");
case PAM_ABORT:
return _("Critical error - immediate abort");
case PAM_OPEN_ERR:
return _("Failed to load module");
case PAM_SYMBOL_ERR:
return _("Symbol not found");
case PAM_SERVICE_ERR:
return _("Error in service module");
case PAM_SYSTEM_ERR:
return _("System error");
case PAM_BUF_ERR:
return _("Memory buffer error");
case PAM_PERM_DENIED:
return _("Permission denied");
case PAM_AUTH_ERR:
return _("Authentication failure");
case PAM_CRED_INSUFFICIENT:
return _("Insufficient credentials to access authentication data");
case PAM_AUTHINFO_UNAVAIL:
return _("Authentication service cannot retrieve authentication info");
case PAM_USER_UNKNOWN:
return _("User not known to the underlying authentication module");
case PAM_MAXTRIES:
return _("Have exhausted maximum number of retries for service");
case PAM_NEW_AUTHTOK_REQD:
return _("Authentication token is no longer valid; new one required");
case PAM_ACCT_EXPIRED:
return _("User account has expired");
case PAM_SESSION_ERR:
return _("Cannot make/remove an entry for the specified session");
case PAM_CRED_UNAVAIL:
return _("Authentication service cannot retrieve user credentials");
case PAM_CRED_EXPIRED:
return _("User credentials expired");
case PAM_CRED_ERR:
return _("Failure setting user credentials");
case PAM_NO_MODULE_DATA:
return _("No module specific data is present");
case PAM_BAD_ITEM:
return _("Bad item passed to pam_*_item()");
case PAM_CONV_ERR:
return _("Conversation error");
case PAM_AUTHTOK_ERR:
return _("Authentication token manipulation error");
case PAM_AUTHTOK_RECOVERY_ERR:
return _("Authentication information cannot be recovered");
case PAM_AUTHTOK_LOCK_BUSY:
return _("Authentication token lock busy");
case PAM_AUTHTOK_DISABLE_AGING:
return _("Authentication token aging disabled");
case PAM_TRY_AGAIN:
return _("Failed preliminary check by password service");
case PAM_IGNORE:
return _("The return value should be ignored by PAM dispatch");
case PAM_MODULE_UNKNOWN:
return _("Module is unknown");
case PAM_AUTHTOK_EXPIRED:
return _("Authentication token expired");
case PAM_CONV_AGAIN:
return _("Conversation is waiting for event");
case PAM_INCOMPLETE:
return _("Application needs to call libpam again");
}
return _("Unknown PAM error");
}
可见,虽然函数有两个参数,但实际上第一个参数pam_handle_t *pamh并未实际使用到。函数的作用一目了然,就是 将各种结果宏定义转换为易于理解的字符串,类似于Linux中的strerror函数。
更多函数请看后续文章。