Я попробовал пример использования pam в следующей ссылке с некоторыми изменениями https://docs.oracle.com/cd/E19253-01/816-4863/pam-20/index.html
main(int argc, char **argv)
{
struct pam_conv conv = { pam_tty_conv, NULL };
pam_handle_t *pamh;
struct passwd *pw;
int err;
disable_kbd_signals();
if ((pw = getpwuid(getuid())) == NULL) {
(void) fprintf(stderr, "plock: Can't get username: %s\n",
strerror(errno));
exit(1);
}
/* Initialize PAM framework */
err = pam_start("password-auth", pw->pw_name, &conv, &pamh);
if (err != PAM_SUCCESS) {
(void) fprintf(stderr, "plock: pam_start failed: %s\n",
pam_strerror(pamh, err));
exit(1);
}
/* Authenticate user in order to unlock screen */
do {
(void) fprintf(stderr, "Terminal locked for %s. ", pw->pw_name);
err = pam_authenticate(pamh, 0);
if (err == PAM_USER_UNKNOWN) {
logout();
} else if (err != PAM_SUCCESS) {
(void) fprintf(stderr, "Invalid password.\n");
}
} while (err != PAM_SUCCESS);
/* Make sure account and password are still valid */
switch (err = pam_acct_mgmt(pamh, 0)) {
case PAM_SUCCESS:
/* The user's password has expired. Get a new one */
err = pam_chauthtok(pamh, 0);
fprintf(stderr, "Error : %d \n", err);
if (err != PAM_SUCCESS)
logout();
break;
default:
logout();
}if (pam_setcred(pamh, PAM_REFRESH_CRED) != PAM_SUCCESS){
logout();}(void) pam_end(pamh, 0);
return(0);
/*NOTREACHED*/}
Код в приведенной выше ссылке предназначен для смены пароля, если срок его действия истек. Я изменил его, чтобы изменить пароль, хотя срок действия пароля не истек. ie pam_chauthtok будет вызываться во всех случаях. Также я изменил имя сервиса на «passwd», так как plock имени сервиса в данной ссылке не доступен по пути /etc/pam.d
. pam_chauthtok запрашивает смену пароля. Но это происходит с ошибкой манипулирования токеном аутентификации (PAM_AUTHTOK_ERR - 20). Кто-нибудь заметил эту ошибку? Я что-то не так делаю или как это исправить? Я пробовал другие имена сервисов, такие как su, sudo, login et c. Но все терпит неудачу с той же ошибкой.