version 1.6, 2002/08/29 00:27:52
|
version 1.12, 2003/03/13 23:09:35
|
|
|
// | // |
// Author: Nag Boranna, Hewlett-Packard Company(nagaraja_boranna@hp.com) | // Author: Nag Boranna, Hewlett-Packard Company(nagaraja_boranna@hp.com) |
// | // |
// Modified By: |
// Modified By: Yi Zhou, Hewlett-Packard Company(yi_zhou@hp.com) |
|
// : Sushma Fernandes, Hewlett-Packard Company |
|
// (sushma_fernandes@hp.com) |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
#include <Pegasus/Common/Destroyer.h> | #include <Pegasus/Common/Destroyer.h> |
#include <Pegasus/Config/ConfigManager.h> | #include <Pegasus/Config/ConfigManager.h> |
| |
|
#ifdef PEGASUS_OS_HPUX |
|
#include <pwd.h> |
|
#include <prot.h> |
|
#endif |
|
|
#include "PAMBasicAuthenticator.h" | #include "PAMBasicAuthenticator.h" |
| |
| |
|
|
| |
#include <security/pam_appl.h> | #include <security/pam_appl.h> |
| |
|
#define BUFFERLEN 1024 |
| |
/** | /** |
Constant representing the Basic authentication challenge header. | Constant representing the Basic authentication challenge header. |
|
|
/** Service name for pam_start */ | /** Service name for pam_start */ |
const char *service = "wbem"; | const char *service = "wbem"; |
| |
const char* userPassword = 0; |
typedef struct |
|
{ |
|
CString userPassword; |
|
} APP_DATA; |
| |
/* constructor. */ | /* constructor. */ |
PAMBasicAuthenticator::PAMBasicAuthenticator() | PAMBasicAuthenticator::PAMBasicAuthenticator() |
|
|
_realm.append(":"); | _realm.append(":"); |
_realm.append(port); | _realm.append(port); |
| |
|
#ifdef PEGASUS_OS_HPUX |
|
// |
|
// get the configured usePAMAuthentication flag |
|
// |
|
|
|
if (String::equal( |
|
configManager->getCurrentValue("usePAMAuthentication"), "true")) |
|
{ |
|
_usePAM = true; |
|
} |
|
else |
|
{ |
|
_usePAM = false; |
|
} |
|
#endif |
|
|
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
|
|
PEG_METHOD_ENTER(TRC_AUTHENTICATION, | PEG_METHOD_ENTER(TRC_AUTHENTICATION, |
"PAMBasicAuthenticator::authenticate()"); | "PAMBasicAuthenticator::authenticate()"); |
| |
|
Boolean authenticated; |
|
|
|
#ifndef PEGASUS_OS_HPUX |
|
authenticated = _authenticateByPAM(userName, password); |
|
#else |
|
if (_usePAM) |
|
{ |
|
// |
|
// Check if the system has been converted to a trusted system. |
|
// ATTN-SF-P3-20030211 - This code to use getpwpwnam on a trusted sytem has |
|
// been added as there is a known problem with trusted mode with PAM based |
|
// Authentication. |
|
// |
|
|
|
if (iscomsec()) |
|
{ |
|
authenticated = false; |
|
String currPassword = String::EMPTY; |
|
String encryptedPassword = String::EMPTY; |
|
String saltStr = String::EMPTY; |
|
char* userNamecstr = strcpy( |
|
new char[strlen(userName.getCString()) + 1], |
|
userName.getCString()); |
|
|
|
// system is a trusted system |
|
// use interface getprpwnam to get pr_passwd structure |
|
|
|
struct pr_passwd * pwd; |
|
|
|
// getprpwnam returns a pointer to a pr_passwd structure upon success |
|
if ( (pwd = getprpwnam(userNamecstr)) != NULL) |
|
{ |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"getprpwnam call successful."); |
|
// get user's password from pr_passwd structure |
|
currPassword = pwd->ufld.fd_encrypt; |
|
} |
|
delete [] userNamecstr; |
|
|
|
// |
|
// Check if the specified password mathches user's password |
|
// |
|
saltStr = currPassword.subString(0,2); |
|
|
|
encryptedPassword = System::encryptPassword(password.getCString(), |
|
saltStr.getCString()); |
|
|
|
if (String::equal(currPassword, encryptedPassword)) |
|
{ |
|
authenticated = true; |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"Password match successful."); |
|
} |
|
} |
|
else |
|
{ |
|
authenticated = _authenticateByPAM(userName, password); |
|
} |
|
} |
|
else |
|
{ |
|
authenticated = _authenticateByPwnam(userName.getCString(), password); |
|
} |
|
#endif |
|
|
|
PEG_METHOD_EXIT(); |
|
return (authenticated); |
|
} |
|
|
|
Boolean PAMBasicAuthenticator::_authenticateByPAM( |
|
const String& userName, |
|
const String& password) |
|
{ |
|
PEG_METHOD_ENTER(TRC_AUTHENTICATION, |
|
"PAMBasicAuthenticator::_authenticateByPAM()"); |
|
|
Boolean authenticated = false; | Boolean authenticated = false; |
struct pam_conv pconv; | struct pam_conv pconv; |
pam_handle_t *phandle; | pam_handle_t *phandle; |
char *name; | char *name; |
|
APP_DATA mydata; |
|
|
|
// |
|
// Store the password for PAM authentication |
|
// |
|
mydata.userPassword = password.getCString(); |
| |
pconv.conv = PAMBasicAuthenticator::PAMCallback; | pconv.conv = PAMBasicAuthenticator::PAMCallback; |
pconv.appdata_ptr = NULL; |
pconv.appdata_ptr = &mydata; |
| |
userPassword = password.getCString(); |
// WARNING: Should only be uncommented for debugging in a secure environment. |
|
// Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
// "PAMBasicAuthenticator::_authenticateByPAM() - userName = %s; userPassword = %s", |
|
// (const char *)userName.getCString(), (const char *)password.getCString()); |
| |
// | // |
//Call pam_start since you need to before making any other PAM calls | //Call pam_start since you need to before making any other PAM calls |
|
|
if ( ( pam_start(service, | if ( ( pam_start(service, |
(const char *)userName.getCString(), &pconv, &phandle) ) != PAM_SUCCESS ) | (const char *)userName.getCString(), &pconv, &phandle) ) != PAM_SUCCESS ) |
{ | { |
userPassword = 0; |
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return (authenticated); | return (authenticated); |
} | } |
|
|
// | // |
if ( ( pam_authenticate(phandle, 0) ) == PAM_SUCCESS ) | if ( ( pam_authenticate(phandle, 0) ) == PAM_SUCCESS ) |
{ | { |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"pam_authenticate successful."); |
// | // |
//Call pam_acct_mgmt, to check if the user account is valid. This includes | //Call pam_acct_mgmt, to check if the user account is valid. This includes |
//checking for password and account expiration, as well as verifying access | //checking for password and account expiration, as well as verifying access |
|
|
// | // |
if ( ( pam_acct_mgmt(phandle, 0) ) == PAM_SUCCESS ) | if ( ( pam_acct_mgmt(phandle, 0) ) == PAM_SUCCESS ) |
{ | { |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"pam_acct_mgmt successful."); |
authenticated = true; | authenticated = true; |
} | } |
} | } |
|
|
// | // |
pam_end(phandle, 0); | pam_end(phandle, 0); |
| |
userPassword = 0; |
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
| |
return (authenticated); | return (authenticated); |
} | } |
| |
|
#ifdef PEGASUS_OS_HPUX |
|
Boolean PAMBasicAuthenticator::_authenticateByPwnam( |
|
const char * userName, |
|
const String& password) |
|
{ |
|
PEG_METHOD_ENTER(TRC_AUTHENTICATION, |
|
"PAMBasicAuthenticator::_authenticateByPwnam()"); |
|
|
|
Boolean authenticated = false; |
|
|
|
String currPassword = String::EMPTY; |
|
String encryptedPassword = String::EMPTY; |
|
String saltStr = String::EMPTY; |
|
|
|
// |
|
// check if the system has been converted to a trusted system. |
|
// |
|
|
|
if (iscomsec()) |
|
{ |
|
// system is a trusted system |
|
// use interface getprpwnam to get pr_passwd structure |
|
|
|
struct pr_passwd * pwd; |
|
|
|
char* _userName = strcpy(new char[strlen(userName) + 1], userName); |
|
|
|
// getprpwnam returns a pointer to a pr_passwd structure upon success |
|
if ( (pwd = getprpwnam(_userName)) != NULL) |
|
{ |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"getprpwnam successful."); |
|
// get user's password from pr_passwd structure |
|
currPassword = pwd->ufld.fd_encrypt; |
|
} |
|
|
|
delete [] _userName; |
|
} |
|
else |
|
{ |
|
// |
|
// system is not a trusted system |
|
// use reentrant interface getpwnam_r to get password structure |
|
// |
|
struct passwd pwd; |
|
struct passwd *result; |
|
char pwdBuffer[BUFFERLEN]; |
|
|
|
// getpwnam_r returns zero upon success |
|
if (getpwnam_r(userName, &pwd, pwdBuffer, BUFFERLEN, &result) == 0) |
|
{ |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"getpwnam_r successful."); |
|
// get user's password from password file |
|
currPassword = pwd.pw_passwd; |
|
} |
|
} |
|
|
|
// |
|
// Check if the specified password mathches user's password |
|
// |
|
saltStr = currPassword.subString(0,2); |
|
|
|
encryptedPassword = System::encryptPassword(password.getCString(), |
|
saltStr.getCString()); |
|
|
|
if (String::equal(currPassword, encryptedPassword)) |
|
{ |
|
authenticated = true; |
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
|
"Password match successful."); |
|
} |
|
|
|
PEG_METHOD_EXIT(); |
|
|
|
return (authenticated); |
|
} |
|
#endif |
|
|
// | // |
// Create authentication response header | // Create authentication response header |
// | // |
|
|
return (responseHeader); | return (responseHeader); |
} | } |
| |
|
#if defined PEGASUS_OS_LINUX |
|
Sint32 PAMBasicAuthenticator::PAMCallback(Sint32 num_msg, const struct pam_message **msg, |
|
struct pam_response **resp, void *appdata_ptr) |
|
#else |
Sint32 PAMBasicAuthenticator::PAMCallback(Sint32 num_msg, struct pam_message **msg, | Sint32 PAMBasicAuthenticator::PAMCallback(Sint32 num_msg, struct pam_message **msg, |
struct pam_response **resp, void *appdata_ptr) | struct pam_response **resp, void *appdata_ptr) |
|
#endif |
{ | { |
PEG_METHOD_ENTER(TRC_AUTHENTICATION, | PEG_METHOD_ENTER(TRC_AUTHENTICATION, |
"PAMBasicAuthenticator::PAMCallback()"); | "PAMBasicAuthenticator::PAMCallback()"); |
|
|
|
// |
|
// Copy the application specific data from the PAM structure. |
|
// |
|
APP_DATA *mydata; |
|
mydata = (APP_DATA *) appdata_ptr; |
|
|
// | // |
// Allocate the response buffers | // Allocate the response buffers |
// | // |
|
|
return PAM_CONV_ERR; | return PAM_CONV_ERR; |
} | } |
| |
for ( Uint32 i = 0; i < num_msg; i++ ) |
for ( Sint32 i = 0; i < num_msg; i++ ) |
{ | { |
switch ( msg[i]->msg_style ) | switch ( msg[i]->msg_style ) |
{ | { |
|
|
// copy the user password | // copy the user password |
// | // |
resp[i]->resp = (char *)malloc(PAM_MAX_MSG_SIZE); | resp[i]->resp = (char *)malloc(PAM_MAX_MSG_SIZE); |
strcpy(resp[i]->resp, userPassword); |
strcpy(resp[i]->resp, mydata->userPassword); |
resp[i]->resp_retcode = 0; | resp[i]->resp_retcode = 0; |
break; | break; |
| |