Я нашел в Интернете фрагмент кода, который показался мне хорошим примером — http://www.freebsd.org/doc/en/articles/pam/article.html#pam-sample-appl.
К сожалению, он не работает должным образом с учетными записями, которые требуют смены пароля при первом входе в систему. Когда я su - user
(из учетной записи без полномочий root), у меня правильно запрашивается пароль, а затем смена пароля. Когда я запускаю свою программу, у меня запрашивается пароль, но у меня, увы, не запрашивается смена пароля, и внутри кода у меня нет указаний на то, что будет даже такая необходимость. В чем проблема?
Отладка PAM показывает мне только это:
Mar 25 11:27:33 S-78 pam: pam_unix(su:auth): authentication failure; logname=greg uid=502 euid=502 tty=/dev/pts/4 ruser=greg rhost=SIR-78 user=tg
Вывод программы, показанной ниже, выглядит следующим образом:
-bash-3.2$ ./pam tg
Password:
pam_authenticate = 7
pam_acct_mgmt = 0
Sorry - pam_err = 17
Вот часть немного измененного кода:
pam_start("su", user, &pamc, &pamh);
/* set some items */
gethostname(hostname, sizeof(hostname));
if ((pam_err = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS)
goto pamerr;
user = getlogin();
if ((pam_err = pam_set_item(pamh, PAM_RUSER, user)) != PAM_SUCCESS)
goto pamerr;
tty = ttyname(STDERR_FILENO);
if ((pam_err = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS)
goto pamerr;
/* authenticate the applicant */
if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
{
printf( "pam_authenticate = %d\n", ( int )pam_err ) ; /* returns error 7 - PAM_AUTH_ERR */
pam_err = pam_acct_mgmt(pamh, 0) ;
printf( "pam_acct_mgmt = %d\n", ( int )pam_err ) ; /* returns no error! */
}
/* establish the requested credentials */
if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) /* returns error 17 - PAM_CRED_ERR */
goto pamerr;
Программа выше использует функцию диалога, скопированную отсюда: http://www.freebsd.org/doc/en/articles/pam/article.html#pam-sample-conv
Я также использовал misc_conv
, объявленный в security/pam_misc.h
, и доступный в -lpam_misc
, но я получил тот же результат - нет запроса на изменение пароля или никаких указаний на то, что это необходимо.
Любая идея, как я могу справиться с этим? Если я удаляю функцию разговора, я получаю те же ошибки, за исключением того, что не предлагается ввести пароль.