version 1.14.4.1, 2004/03/25 21:29:58
|
version 1.20, 2004/05/14 18:39:22
|
|
|
#include <sys/resource.h> | #include <sys/resource.h> |
#endif | #endif |
| |
|
|
#include "PAMBasicAuthenticator.h" | #include "PAMBasicAuthenticator.h" |
| |
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
|
|
| |
#define BUFFERLEN 1024 | #define BUFFERLEN 1024 |
| |
|
#if defined (PEGASUS_USE_PAM_STANDALONE_PROC) |
|
|
|
#if defined (PEGASUS_HAS_SIGNALS) |
|
|
|
#if defined (PEGASUS_OS_LINUX) |
|
|
|
#include <sys/types.h> |
|
#include <sys/wait.h> |
|
#include <sys/signal.h> |
|
|
|
void childSignalHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig) |
|
{ |
|
pid_t cpid = 0; |
|
int waitcode = 0; |
|
PEG_METHOD_ENTER(TRC_SERVER, "childSignalHandler"); |
|
|
|
if (s_n == PEGASUS_SIGCHLD) { |
|
Tracer::trace(TRC_SERVER, Tracer::LEVEL4, "Signal from a child %d", s_n); |
|
while( (cpid = waitpid(waitcode, NULL, WNOHANG)) > 0) |
|
; |
|
|
|
if(cpid < 0) |
|
{ |
|
Tracer::trace(TRC_SERVER, Tracer::LEVEL4, "waitpid error: %d", errno); |
|
/* Reset the error */ |
|
errno=0; |
|
} |
|
} |
|
PEG_METHOD_EXIT(); |
|
} |
|
#endif |
|
#endif |
|
#endif |
/** | /** |
Constant representing the Basic authentication challenge header. | Constant representing the Basic authentication challenge header. |
*/ | */ |
|
|
_realm.append(port); | _realm.append(port); |
| |
// | // |
// Check for platforms that allow PAM |
// Check for platforms that allow PAM Standalone Process |
// | // |
#if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) |
|
// |
|
// get the configured usePAMAuthentication flag |
|
// |
|
if (String::equal( |
|
configManager->getCurrentValue("usePAMAuthentication"), "true")) |
|
{ |
|
_usePAM = true; |
|
} |
|
else |
|
{ |
|
_usePAM = false; |
|
} |
|
#if defined(PEGASUS_USE_PAM_STANDALONE_PROC) | #if defined(PEGASUS_USE_PAM_STANDALONE_PROC) |
// | // |
// Set up the separate process to do PAM Authentication | // Set up the separate process to do PAM Authentication |
// | // |
if (_usePAM) |
|
{ |
|
_pamBasicAuthenticatorStandAlone = | _pamBasicAuthenticatorStandAlone = |
new PAMBasicAuthenticatorStandAlone(); | new PAMBasicAuthenticatorStandAlone(); |
} |
|
#endif |
|
|
|
#endif | #endif |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
|
|
Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, | Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4, |
"Authentication Mutex lock."); | "Authentication Mutex lock."); |
AutoMutex lock(_authSerializeMutex); | AutoMutex lock(_authSerializeMutex); |
|
|
if (_usePAM) |
|
{ |
|
authenticated = | authenticated = |
_pamBasicAuthenticatorStandAlone->authenticate(userName, | _pamBasicAuthenticatorStandAlone->authenticate(userName, |
password); | password); |
} |
|
else |
|
{ |
|
authenticated = _authenticateByPwnam(userName.getCString(), password); |
|
} |
|
#endif | #endif |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
|
|
return (authenticated); | return (authenticated); |
} | } |
| |
#if defined(PEGASUS_USE_PAM_STANDALONE_PROC) |
|
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 defined(PEGASUS_OS_HPUX) |
|
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 |
|
{ |
|
#endif |
|
// |
|
// 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; |
|
} |
|
#if defined(PEGASUS_OS_HPUX) |
|
} |
|
#endif |
|
|
|
// |
|
// 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 |
// | // |
|
|
} | } |
if (continue_PAMauthentication) | if (continue_PAMauthentication) |
{ | { |
|
#if defined (PEGASUS_OS_LINUX) |
|
/* |
|
From signal manpage on Linux: |
|
" According to POSIX (3.3.1.3) it is unspecified what happens when |
|
SIGCHLD is set to SIG_IGN. Here the BSD and SYSV behaviours differ, |
|
causing BSD software that sets the action for SIGCHLD to SIG_IGN to |
|
fail on Linux." |
|
|
|
On Linux, when you perform a "system" it calls wait(). If you have ignored |
|
SIGCHLD, a POSIX-conformant system is allowed to collect zombies immediately |
|
rather than holding them for you to wait for. And you end up with "system" |
|
returning non-zero return code instead of zero return code for sucessfull |
|
calls. |
|
|
|
HP-UX being a SYSV system behaves differently. |
|
*/ |
|
|
|
getSigHandle()->registerHandler(PEGASUS_SIGCHLD, childSignalHandler); |
|
getSigHandle()->activate(PEGASUS_SIGCHLD); |
|
#else |
SignalHandler::ignore(PEGASUS_SIGCHLD); // Allows child death | SignalHandler::ignore(PEGASUS_SIGCHLD); // Allows child death |
|
#endif |
if ((pid = fork()) < 0) | if ((pid = fork()) < 0) |
{ | { |
continue_PAMauthentication = false; | continue_PAMauthentication = false; |
|
|
// | // |
// Get environment variables: | // Get environment variables: |
// | // |
const char* pegasusHome = getenv("PEGASUS_HOME"); |
String certpath = ConfigManager::getHomedPath( |
|
PEGASUS_PAM_STANDALONE_PROC_NAME); |
String certpath = FileSystem::getAbsolutePath( |
|
pegasusHome, PEGASUS_PAM_STANDALONE_PROC_NAME); |
|
if (execl((const char*)certpath.getCString(), | if (execl((const char*)certpath.getCString(), |
(const char*)certpath.getCString(), (char*)0) < 0) | (const char*)certpath.getCString(), (char*)0) < 0) |
{ | { |