version 1.6, 2006/01/30 16:18:29 |
version 1.6.30.2, 2006/12/31 21:31:06 |
| |
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Ben Heilbronn, Hewlett-Packard Company(ben_heilbronn@hp.com) | |
// | |
// Parts of this code originated within PAMBasicAuthenticator. | |
// | |
// Modified By: Sushma Fernandes, Hewlett-Packard Company(sushma_fernandes@hp.com) | |
// | |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/System.h> | |
#include <Pegasus/Common/String.h> | |
#include <Pegasus/Common/FileSystem.h> | |
#include <Pegasus/Common/PegasusVersion.h> | |
#include <Pegasus/Security/Authentication/PAMBasicAuthenticator.h> | |
| |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/resource.h> | |
#include <string.h> | |
#include <strings.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
| |
#include "cimservera.h" | #include "cimservera.h" |
| #include <cstdio> |
| #include <Executor/Executor.h> |
| |
PEGASUS_USING_STD; | int main(int argc, char* argv[]) |
| |
PEGASUS_NAMESPACE_BEGIN | |
| |
#include <security/pam_appl.h> | |
| |
#define BUFFERLEN 1024 | |
#define HEADER_LEN 4 | |
| |
typedef struct | |
{ | |
CString userPassword; | |
} APP_DATA; | |
| |
// Initialize the constants. | |
| |
const char Cimservera::OPERATION_PAM_AUTHENTICATION = 'A'; | |
| |
const char Cimservera::OPERATION_PAM_ACCT_MGMT = 'M'; | |
| |
const char Cimservera::PAM_OPERATION_SUCCESS = 'T'; | |
| |
const char Cimservera::PAM_OPERATION_FAILURE = 'F'; | |
| |
/* constructor. */ | |
Cimservera::Cimservera() | |
{ | |
} | |
| |
/* destructor. */ | |
Cimservera::~Cimservera() | |
{ | |
} | |
| |
Boolean Cimservera::authenticateByPAM( | |
const String& userName, | |
const String& password) | |
{ | |
Boolean authenticated = false; | |
struct pam_conv pconv; | |
pam_handle_t *phandle; | |
char *name; | |
APP_DATA mydata; | |
| |
const char *service = "wbem"; | |
| |
// | |
// Store the password for PAM authentication | |
// | |
mydata.userPassword = password.getCString(); | |
| |
pconv.conv = Cimservera::PAMCallback; | |
pconv.appdata_ptr = &mydata; | |
| |
// | |
//Call pam_start since you need to before making any other PAM calls | |
// | |
if ( ( pam_start(service, | |
(const char *)userName.getCString(), &pconv, &phandle) ) != PAM_SUCCESS ) | |
{ | { |
return (authenticated); | // Check argumnents. |
} | |
| |
// | if (argc != 2) |
//Call pam_authenticate to authenticate the user | |
// | |
if ( ( pam_authenticate(phandle, 0) ) == PAM_SUCCESS ) | |
{ | { |
// | fprintf(stderr, "Usage: %s <socket-number>\n", argv[0]); |
//Call pam_acct_mgmt, to check if the user account is valid. This includes | exit(1); |
//checking for password and account expiration, as well as verifying access | |
//hour restrictions. | |
// | |
if ( ( pam_acct_mgmt(phandle, 0) ) == PAM_SUCCESS ) | |
{ | |
authenticated = true; | |
} | |
} | } |
| |
// | // Open socket stream. |
//Call pam_end to end our PAM work | |
// | |
pam_end(phandle, 0); | |
| |
return (authenticated); | |
} | |
| |
#if defined PEGASUS_OS_LINUX | |
Sint32 Cimservera::PAMCallback(Sint32 num_msg, const struct pam_message **msg, | |
struct pam_response **resp, void *appdata_ptr) | |
#else | |
Sint32 Cimservera::PAMCallback(Sint32 num_msg, struct pam_message **msg, | |
struct pam_response **resp, void *appdata_ptr) | |
#endif | |
{ | |
// | |
// Copy the application specific data from the PAM structure. | |
// | |
APP_DATA *mydata; | |
mydata = (APP_DATA *) appdata_ptr; | |
| |
// | |
// Allocate the response buffers | |
// | |
if ( num_msg > 0 ) | |
{ | |
// | |
// Since resp->resp needs to be initialized in all possible scenarios, | |
// use calloc for memory allocation. | |
// | |
*resp = (struct pam_response *)calloc(num_msg, sizeof(struct pam_response)); | |
| |
if ( *resp == NULL ) | int sock; |
{ | |
return PAM_BUF_ERR; | |
} | |
} | |
else | |
{ | { |
return PAM_CONV_ERR; | char* end; |
} | long x = strtoul(argv[1], &end, 10); |
| |
for ( Sint32 i = 0; i < num_msg; i++ ) | if (*end != '\0') |
{ | |
switch ( msg[i]->msg_style ) | |
{ | { |
case PAM_PROMPT_ECHO_OFF: | fprintf(stderr, "%s : bad socket argument: %s\n", argv[0], argv[1]); |
// | exit(1); |
// copy the user password | |
// | |
resp[i]->resp = (char *)malloc(PAM_MAX_MSG_SIZE); | |
strcpy(resp[i]->resp, mydata->userPassword); | |
resp[i]->resp_retcode = 0; | |
break; | |
| |
default: | |
return PAM_CONV_ERR; | |
} | |
} | } |
| |
return PAM_SUCCESS; | sock = int(x); |
} | } |
| |
Boolean Cimservera::performAcctMgmt (const String& userName) | // Wait on request. |
{ | |
Boolean authenticated = false; | |
struct pam_conv pconv; | |
pam_handle_t *phandle; | |
char *name; | |
APP_DATA mydata; | |
| |
const char *service = "wbem"; | |
pconv.conv = PAMBasicAuthenticator::pamValidateUserCallback; | |
pconv.appdata_ptr = &mydata; | |
| |
// | CimserveraRequest request; |
// Call pam_start since you need to before making any other PAM calls | |
// | |
if ( pam_start(service, | |
(const char *)userName.getCString(), &pconv, &phandle) != PAM_SUCCESS) | |
{ | |
return (authenticated); | |
} | |
| |
// | // Wait on request. |
// Call pam_acct_mgmt, to check if the user account is valid. This include s | if (CimserveraRecv(sock, &request, sizeof(request)) != sizeof(request)) |
// checking for account expiration, as well as verifying access | |
// hour restrictions. | |
// | |
if ( pam_acct_mgmt(phandle, 0) == PAM_SUCCESS ) | |
{ | { |
authenticated = true; | close(sock); |
| return -1; |
} | } |
| |
// | if (strcmp(request.arg0, "authenticate") == 0) |
//Call pam_end to end our PAM work | |
// | |
pam_end(phandle, 0); | |
| |
return (authenticated); | |
} | |
| |
PEGASUS_NAMESPACE_END; | |
PEGASUS_USING_PEGASUS; | |
| |
int main(int argc, char* argv[]) | |
{ | |
int n, len; | |
char username[BUFFERLEN], password[BUFFERLEN], operation[BUFFERLEN]; | |
char * _username = &username[0]; | |
char * _password = &password[0]; | |
char username_len[10], password_len[10], operation_len[10]; | |
char return_buf[2]; | |
| |
typedef struct | |
{ | { |
CString userPassword; | int status = PAMAuthenticate(request.arg1, request.arg2); |
} APP_DATA; | CimserveraSend(sock, &status, sizeof(status)); |
| |
Boolean authenticated; | |
| |
// STDIN and STDOUT are used on the back-end for reading and writing | |
| |
for (;;) { // Just loop on username/passwords/opcode | |
| |
authenticated = false; | |
| |
// Read in the username | |
| |
len = read(STDIN_FILENO, username_len, HEADER_LEN); | |
if (len != HEADER_LEN) { | |
break; | |
} | |
username_len[HEADER_LEN] = '\0'; | |
n = atoi(username_len); | |
read(STDIN_FILENO, username, n); | |
username[n] = '\0'; | |
| |
// Read in the password | |
| |
len = read(STDIN_FILENO, password_len, HEADER_LEN); | |
if (len != HEADER_LEN) { | |
break; | |
} | |
password_len[HEADER_LEN] = '\0'; | |
n = atoi(password_len); | |
read(STDIN_FILENO, password, n); | |
password[n] = '\0'; | |
| |
// Read in the operation | |
| |
len = read(STDIN_FILENO, operation_len, HEADER_LEN); | |
if (len != HEADER_LEN) { | |
break; | |
} | } |
operation_len[HEADER_LEN] = '\0'; | else if (strcmp(request.arg0, "validateUser") == 0) |
n = atoi(operation_len); | |
read(STDIN_FILENO, operation, n); | |
operation[n] = '\0'; | |
| |
// | |
// Check the operation flag. | |
// | |
if (operation[0] == Cimservera::OPERATION_PAM_AUTHENTICATION) | |
{ | { |
authenticated = Cimservera::authenticateByPAM(_username, _password); | int status = PAMValidateUser(request.arg1); |
| CimserveraSend(sock, &status, sizeof(status)); |
} | } |
else if (operation[0] == Cimservera::OPERATION_PAM_ACCT_MGMT) | else |
{ | { |
authenticated = Cimservera::performAcctMgmt(_username); | fprintf(stderr, "%s: bad request\n", argv[0]); |
| close(sock); |
| exit(1); |
} | } |
| |
if (authenticated) | close(sock); |
{ | |
return_buf[0] = Cimservera::PAM_OPERATION_SUCCESS; | |
} else | |
{ | |
return_buf[0] = Cimservera::PAM_OPERATION_FAILURE; | |
} | |
return_buf[1] = '\0'; | |
| |
write(STDOUT_FILENO, return_buf, 1); | exit(0); |
} | return 0; |
} | } |