Код C ++ использует PAM (libpamc.so lib и его соответствующие методы) в качестве метода аутентификации локальных пользователей и пользователей NIS на машинах RHEL и Sun. Пример кода ниже.
Вопрос — этот код может работать с аутентификацией LDAP без изменений? Я не вижу адекватного одобрения в документации, у меня нет развернутого LDAP, чтобы проверить это практически.
Спасибо!
Образец:
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include <stdexcept>
#include <unistd.h>
#include <sys/param.h>
#include <sstream>
#ifdef __unix__
#include <netdb.h>
#endifusing namespace std;
static string PSW;
int conversation_f(int nIn ,
#ifdef __linux__
const
#endif
struct pam_message **pamMsg, struct pam_response ** pamResp, void *data)
{
struct pam_response *aresp;
if (nIn<=0 || nIn>PAM_MAX_NUM_MSG)
{return (PAM_CONV_ERR);}
if (PSW.empty())
{return(PAM_BUF_ERR);}
if ((aresp = (pam_response*)calloc(nIn, sizeof *aresp)) == NULL)
{return(PAM_BUF_ERR);}for (int mm=0; mm <nIn;mm++)
{
aresp[mm].resp_retcode=0;
char *hold=(char*) malloc(PSW.size()+1);
strcpy(hold, PSW.c_str());
aresp[mm].resp=hold ;
pamResp[mm]=&aresp[mm] ;
}
return(PAM_SUCCESS);
}
int authenticatThruPAM(string user, string psw)
{
char hostname[MAXHOSTNAMELEN];
pam_handle_t *pamh;
struct pam_conv pamc = {&conversation_f, NULL };
int pam_err;
stringstream out;
// set up global password variable
PSW = psw;
// pam start
if ((pam_err = pam_start("su", user.c_str(), &pamc, &pamh)) != PAM_SUCCESS)
{
out << "pam_start(user=%s)=" << pam_err << " " << pam_strerror(pamh, pam_err);
throw runtime_error(out.str());
}
// get hostname
if ((pam_err = gethostname(hostname, sizeof(hostname))) != 0)
{
out << "gethostname()=" << errno << " " << strerror(errno);
throw runtime_error(out.str());
}
// set up host
if ((pam_err = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS)
{
out << "pam_set_item(PAM_RHOST, hostname=" << hostname << ")=" << pam_err << " " << pam_strerror(pamh, pam_err);
throw runtime_error(out.str());
}
// set up user
if ((pam_err = pam_set_item(pamh, PAM_RUSER, user.c_str())) != PAM_SUCCESS)
{
out << "pam_set_item(PAM_RUSER, user=" << user << ")=" << pam_err << " " << pam_strerror(pamh, pam_err);
throw runtime_error(out.str());
}
// authenticate the applicant
if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
{
out << "pam_authenticate(user=" << user << ")=" << pam_err << " " << pam_strerror(pamh, pam_err);
throw runtime_error(out.str());
}
// determine if the user's account is valid
if ((pam_err = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
{
out << "pam_acct_mgmt(user=" << user << ")=" << pam_err << " " << pam_strerror(pamh, pam_err);
throw runtime_error(out.str());
}
// SUCCESS
cout << "user=" << user << " authenticated successfully" << endl;
// establish the requested credentials
if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) == PAM_SUCCESS)
{ cout << "pam_setcred(PAM_ESTABLISH_CRED) = OK" << endl;}
else
{ cout << "pam_setcred(PAM_ESTABLISH_CRED) = " << pam_strerror(pamh, pam_err) << endl; }// close the session and release PAM resources
if ((pam_err = pam_close_session(pamh, 0)) == PAM_SUCCESS)
{ cout << "pam_close_session()=OK" << endl;}
else
{ cout << "pam_close_session()=" << pam_err << " " << pam_strerror(pamh, pam_err) << endl; }
// close the session and release PAM resources
if ((pam_err = pam_end(pamh, pam_err)) == PAM_SUCCESS)
{ cout << "pam_end()=OK" << endl;}
else
{ cout << "pam_end()=" << pam_err << " "<< pam_strerror(pamh, pam_err) << endl; }
return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
try
{
// get user name and password
string user, psw;
char c;
cout << "Enter user name: ";
cin >> user;
psw = getpass("Enter password: ");
// do PAM authentication
return authenticatThruPAM(user, psw);
}
catch(exception &e)
{
cout << "ERROR! " << e.what() << endl;
return EXIT_FAILURE;
}
catch(...)
{
cout << "ERROR! code: " << errno << " message: " << strerror(errno) << endl;
return EXIT_FAILURE;
}
}
Задача ещё не решена.
Других решений пока нет …