День добрый,
Необходимо внедрить в ПО следующий функционал:
Аутотентификация в программе одного из системных пользователей по логину и паролю (используя PAM).
Проблема следующая: аутотентифицируется только тот пользователь, от имени которого запущена программа.
class MainWindow : public QMainWindow
{
Q_OBJECT
...
public:
QString pcode;
...
private:
QString currUser;
bool authenticated;
...
private slots:
void doAutenticate ();
...
};
int converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data);
Аутотентификация:
void MainWindow::doAutenticate()
{
authenticated = false;
loginDialog dialog(this);
if (dialog.exec())
{
char * user = (char*)dialog.getLogin().toAscii().data();
pcode = dialog.getPassword();
static pam_handle_t *pamh;
struct pam_conv pamc = { converse, this };
// pcode = "";
char hostname[MAXHOSTNAMELEN];
char *ruser;
int retcode = 0;
pam_start("su", user, &pamc, &pamh);
gethostname(hostname, sizeof(hostname));
if ((retcode = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS)
{
qDebug() << "pam_set_item hostname failed. " << QString::fromLocal8Bit(pam_strerror(pamh, retcode));
}
else
{
ruser = getlogin();
if ((retcode = pam_set_item(pamh, PAM_RUSER, ruser)) != PAM_SUCCESS)
{
qDebug() << "pam_set_item remote user failed. " << QString::fromLocal8Bit(pam_strerror(pamh, retcode));
}
if ((retcode = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
{
qDebug() << "pam_authenticate failed. " << QString::fromLocal8Bit(pam_strerror(pamh, retcode));
}
else
{
authenticated = true;
qDebug() << "Authenticated !!!!";
}
}
}
else
{
authenticated = false;
}
updateUser();
}
Функция converse:
int converse(int n, const struct pam_message **msg, struct pam_response **resp, void *data)
{
MainWindow* ob = static_cast<MainWindow*>(data);
QString strp = ob->pcode;
QByteArray ba = strp.toLatin1();
char *pcodec = ba.data();
struct pam_response *aresp;
char buf[PAM_MAX_RESP_SIZE];
int i;
aresp = new pam_response;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
for (i = 0; i < n; ++i) {
aresp[i].resp_retcode = 0;
aresp[i].resp = NULL;
switch (msg[i]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
aresp[i].resp = strdup(pcodec);
if (aresp[i].resp == NULL)
goto fail;
break;
case PAM_PROMPT_ECHO_ON:
fputs(msg[i]->msg, stderr);
if (fgets(buf, sizeof buf, stdin) == NULL)
goto fail;
aresp[i].resp = strdup(buf);
if (aresp[i].resp == NULL)
goto fail;
break;
case PAM_ERROR_MSG:
fputs(msg[i]->msg, stderr);
if (strlen(msg[i]->msg) > 0 &&
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
fputc('\n', stderr);
break;
case PAM_TEXT_INFO:
fputs(msg[i]->msg, stdout);
if (strlen(msg[i]->msg) > 0 &&
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
fputc('\n', stdout);
break;
default:
goto fail;
}
}
*resp = aresp;
return (PAM_SUCCESS);
fail:
for (i = 0; i < n; ++i) {
if (aresp[i].resp != NULL) {
memset(aresp[i].resp, 0, strlen(aresp[i].resp));
free(aresp[i].resp);
}
}
memset(aresp, 0, n * sizeof *aresp);
*resp = NULL;
return (PAM_CONV_ERR);
}
При авторизации любого пользователя, отличного от владельца терминала, с которого запускается программа, pam_strerror возвращает ошибку:
"Сбой при проверке подлинности" Заранее спасибо за помощь.