|
|
|
|
@@ -29,147 +29,257 @@
|
|
|
|
|
*
|
|
|
|
|
* This module needs to be present before any other PAM module which
|
|
|
|
|
* requires the services of miCASAd. It needs to be present
|
|
|
|
|
* the auth stacks of the PAM configuration files.
|
|
|
|
|
* the auth and password stacks of the PAM configuration files.
|
|
|
|
|
*
|
|
|
|
|
* In the auth stack, the functionality of the module is to store
|
|
|
|
|
* the workstation user/password in micasad.
|
|
|
|
|
*
|
|
|
|
|
* In the password stack, the functionality of the module is to capture
|
|
|
|
|
* the new password during change password operation and updating
|
|
|
|
|
* the same in micasad.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "pam_sscs.h"
|
|
|
|
|
|
|
|
|
|
#define PAM_SM_AUTH
|
|
|
|
|
#define PAM_SM_PASSWORD
|
|
|
|
|
#define PAM_SM_ACCOUNT
|
|
|
|
|
#define PAM_SM_SESSION
|
|
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <sys/syslog.h>
|
|
|
|
|
#include <security/pam_modules.h>
|
|
|
|
|
#include <security/_pam_macros.h>
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
|
|
|
|
|
const char **argv)
|
|
|
|
|
/*
|
|
|
|
|
* Running (micasad_status = 1)
|
|
|
|
|
* Not Running (micasad_status = 0)
|
|
|
|
|
*/
|
|
|
|
|
static int micasad_status = 0;
|
|
|
|
|
|
|
|
|
|
int is_micasad_running(void)
|
|
|
|
|
{
|
|
|
|
|
int retVal = 0;
|
|
|
|
|
FILE *pid_file = NULL;
|
|
|
|
|
char pid_str[MICASAD_PID_SIZE];
|
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
|
|
const char *user = NULL;
|
|
|
|
|
const char *wkstnPasswd = NULL;
|
|
|
|
|
pid_file = fopen (MICASAD_PID_FILE, "r");
|
|
|
|
|
if (!pid_file)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
uid_t saved_uid = geteuid();
|
|
|
|
|
struct passwd *passwdEntry = NULL;
|
|
|
|
|
if (!fgets (pid_str, MICASAD_PID_SIZE, pid_file)) {
|
|
|
|
|
fclose (pid_file);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get the username first.
|
|
|
|
|
*/
|
|
|
|
|
retVal = pam_get_user(pamh, &user, NULL);
|
|
|
|
|
fclose (pid_file);
|
|
|
|
|
|
|
|
|
|
if ( PAM_SUCCESS != retVal )
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log( LOG_ERR, "pam_get_user returned error: %d - %s\n",retVal,pam_strerror(pamh,retVal));
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
pid = atoi (pid_str);
|
|
|
|
|
if ( pid < 2 )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
pam_get_item(pamh,PAM_AUTHTOK,(const void**)&wkstnPasswd);
|
|
|
|
|
passwdEntry = getpwnam(user);
|
|
|
|
|
return (!kill(pid, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_micasa_password(const char *user, const char *password)
|
|
|
|
|
{
|
|
|
|
|
uid_t saved_uid = geteuid();
|
|
|
|
|
struct passwd *passwdEntry = NULL;
|
|
|
|
|
int retval = 0;
|
|
|
|
|
|
|
|
|
|
/* Set the desktop password in miCASA */
|
|
|
|
|
passwdEntry = getpwnam(user);
|
|
|
|
|
if( passwdEntry ) {
|
|
|
|
|
/* CASA determines the client uid using the SO_PEERCRED socket option.
|
|
|
|
|
* Hence the euid is temporarily modified to that of the user logging in.
|
|
|
|
|
*/
|
|
|
|
|
if(passwdEntry)
|
|
|
|
|
{
|
|
|
|
|
seteuid( passwdEntry->pw_uid );
|
|
|
|
|
seteuid(passwdEntry -> pw_uid);
|
|
|
|
|
do {
|
|
|
|
|
char *error = NULL;
|
|
|
|
|
SSCS_SECRET_ID_T secretID = {0};
|
|
|
|
|
SSCS_BASIC_CREDENTIAL basicCredential;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
char *error = NULL;
|
|
|
|
|
SSCS_SECRET_ID_T secretID = {0};
|
|
|
|
|
SSCS_BASIC_CREDENTIAL basicCredential;
|
|
|
|
|
int credType;
|
|
|
|
|
void *nsscsIdkHandle = dlopen(NSSCSIDK_LIB, RTLD_NOW);
|
|
|
|
|
if( NULL == nsscsIdkHandle ) {
|
|
|
|
|
pam_sscs_log(LOG_ERR,"Unable to open %s\n", NSSCSIDK_LIB);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *nsscsIdkHandle = dlopen(NSSCSIDK_LIB,RTLD_NOW);
|
|
|
|
|
if( NULL == nsscsIdkHandle )
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log(LOG_ERR,"Unable to open %s\n",NSSCSIDK_LIB);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pNSSCSSetCredential = dlsym(nsscsIdkHandle, "miCASASetCredential");
|
|
|
|
|
if( (error = dlerror()) != NULL ) {
|
|
|
|
|
pam_sscs_log(LOG_ERR,"Unable to find miCASASetCredential symbol.- %s\n",error);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pNSSCSSetCredential = dlsym( nsscsIdkHandle,
|
|
|
|
|
"miCASASetCredential");
|
|
|
|
|
if( (error = dlerror()) != NULL )
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log(LOG_ERR,"Unable to find miCASASetCredential symbol.- %s\n",error);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
secretID.len = strlen(WORKSTATION_SECRET_ID) + 1;
|
|
|
|
|
strcpy(secretID.id,WORKSTATION_SECRET_ID);
|
|
|
|
|
|
|
|
|
|
secretID.len = strlen(WORKSTATION_SECRET_ID) + 1;
|
|
|
|
|
strcpy(secretID.id,WORKSTATION_SECRET_ID);
|
|
|
|
|
memset(&basicCredential,0,sizeof(basicCredential));
|
|
|
|
|
|
|
|
|
|
memset(&basicCredential,0,sizeof(basicCredential));
|
|
|
|
|
if (user && password) {
|
|
|
|
|
basicCredential.unFlags = 0;
|
|
|
|
|
// don't copy a username longer than we can handle
|
|
|
|
|
if ((strlen(user) + 1) > NSSCS_MAX_USERID_LEN) {
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Username is longer than allowed\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
strcpy(basicCredential.username,user);
|
|
|
|
|
basicCredential.unLen = strlen(user) + 1;
|
|
|
|
|
|
|
|
|
|
if (user && wkstnPasswd)
|
|
|
|
|
{
|
|
|
|
|
basicCredential.unFlags = 0;
|
|
|
|
|
// don't copy a username longer than we can handle
|
|
|
|
|
if ((strlen(user) + 1) > NSSCS_MAX_USERID_LEN)
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Username is longer than allowed\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
strcpy(basicCredential.username,user);
|
|
|
|
|
basicCredential.unLen = strlen(user) + 1;
|
|
|
|
|
// don't copy a password longer than we can handle
|
|
|
|
|
if ((strlen(password) + 1) > NSSCS_MAX_PWORD_LEN) {
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Password is longer than allowed\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
strcpy(basicCredential.password,password);
|
|
|
|
|
basicCredential.pwordLen = strlen(password) + 1;
|
|
|
|
|
|
|
|
|
|
// don't copy a password longer than we can handle
|
|
|
|
|
if ((strlen(wkstnPasswd) + 1) > NSSCS_MAX_PWORD_LEN)
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Password is longer than allowed\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
strcpy(basicCredential.password,wkstnPasswd);
|
|
|
|
|
basicCredential.pwordLen = strlen(wkstnPasswd) + 1;
|
|
|
|
|
retval = (*pNSSCSSetCredential) (0,
|
|
|
|
|
&secretID,
|
|
|
|
|
NULL,
|
|
|
|
|
SSCS_CRED_TYPE_BASIC_F,
|
|
|
|
|
&basicCredential,
|
|
|
|
|
NULL);
|
|
|
|
|
if( retval != 0) {
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Setting the default credential failed.Errcode = %d\n",retval);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (0);
|
|
|
|
|
seteuid(saved_uid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
retVal = (*pNSSCSSetCredential) (0,
|
|
|
|
|
&secretID,
|
|
|
|
|
NULL,
|
|
|
|
|
SSCS_CRED_TYPE_BASIC_F,
|
|
|
|
|
&basicCredential,
|
|
|
|
|
NULL);
|
|
|
|
|
if( retVal != 0)
|
|
|
|
|
{
|
|
|
|
|
pam_sscs_log( LOG_ERR,"Setting the default credential failed.Errcode = %d\n",retVal);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}while(0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seteuid(saved_uid);
|
|
|
|
|
/* --- authentication management function --- */
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
|
|
|
|
{
|
|
|
|
|
int retval = 0;
|
|
|
|
|
const char *user = NULL, *wkstnPasswd = NULL;
|
|
|
|
|
|
|
|
|
|
if ( !is_micasad_running() ) {
|
|
|
|
|
pam_sscs_log(LOG_DEBUG, "micasad is not running.\n");
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the username */
|
|
|
|
|
retval = pam_get_user(pamh, &user, NULL);
|
|
|
|
|
if ( PAM_SUCCESS != retval ) {
|
|
|
|
|
pam_sscs_log( LOG_ERR,
|
|
|
|
|
"pam_get_user returned error: %d - %s\n",
|
|
|
|
|
retval,
|
|
|
|
|
pam_strerror(pamh,retval));
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the password */
|
|
|
|
|
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void**)&wkstnPasswd);
|
|
|
|
|
if ( PAM_SUCCESS != retval ) {
|
|
|
|
|
pam_sscs_log(LOG_ERR,
|
|
|
|
|
"pam_get_item returned: %d - %s\n",
|
|
|
|
|
retval,
|
|
|
|
|
pam_strerror(pamh, retval));
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
else if ( !wkstnPasswd ) {
|
|
|
|
|
pam_sscs_log(LOG_AUTHPRIV,
|
|
|
|
|
"pam_get_item returned a NULL pointer for the password\n");
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set the password in micasad*/
|
|
|
|
|
set_micasa_password(user, wkstnPasswd);
|
|
|
|
|
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN
|
|
|
|
|
int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
|
|
|
|
|
,const char **argv)
|
|
|
|
|
int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
|
|
|
|
{
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- account management functions --- */
|
|
|
|
|
/* --- password management function --- */
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN
|
|
|
|
|
int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
|
|
|
|
|
,const char **argv)
|
|
|
|
|
int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
int retval = 0;
|
|
|
|
|
const char *user = NULL, *new_passwd = NULL;
|
|
|
|
|
|
|
|
|
|
/* Get the username */
|
|
|
|
|
retval = pam_get_user(pamh, &user, NULL);
|
|
|
|
|
if ( PAM_SUCCESS != retval ) {
|
|
|
|
|
pam_sscs_log(LOG_ERR,
|
|
|
|
|
"pam_get_user returned: %d - %s\n",
|
|
|
|
|
retval,
|
|
|
|
|
pam_strerror(pamh,retval));
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( flags & PAM_PRELIM_CHECK ) {
|
|
|
|
|
|
|
|
|
|
if ( is_micasad_running() )
|
|
|
|
|
micasad_status = 1;
|
|
|
|
|
else
|
|
|
|
|
micasad_status = 0;
|
|
|
|
|
|
|
|
|
|
return (PAM_SUCCESS);
|
|
|
|
|
} /* End of PAM_PRELIM_CHECK */
|
|
|
|
|
else if ( flags & PAM_UPDATE_AUTHTOK ) {
|
|
|
|
|
|
|
|
|
|
if( !micasad_status ) {
|
|
|
|
|
pam_sscs_log(LOG_DEBUG, "micasad is not running.\n");
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the new password */
|
|
|
|
|
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&new_passwd);
|
|
|
|
|
if( PAM_SUCCESS != retval ) {
|
|
|
|
|
pam_sscs_log(LOG_ERR,
|
|
|
|
|
"pam_get_item returned: %d - %s\n",
|
|
|
|
|
retval,
|
|
|
|
|
pam_strerror(pamh, retval));
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
else if ( !new_passwd ) {
|
|
|
|
|
pam_sscs_log(LOG_AUTHPRIV, "pam_get_item returned a NULL pointer for the new password\n");
|
|
|
|
|
return (retval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set the new password in micasad*/
|
|
|
|
|
set_micasa_password(user, new_passwd);
|
|
|
|
|
|
|
|
|
|
} /*End of PAM_UPDATE_AUTHTOK */
|
|
|
|
|
else {
|
|
|
|
|
pam_sscs_log(LOG_DEBUG, "Neither PAM_PRELIM_CHECK nor PAM_UPDATE_AUTHTOK flag is set.\n");
|
|
|
|
|
return (PAM_AUTH_ERR);
|
|
|
|
|
} /* End of some other flag (Other than PAM_PRELIM_CHECK or PAM_UPDATE_AUTHTOK */
|
|
|
|
|
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- account management function --- */
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN
|
|
|
|
|
int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
|
|
|
|
{
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc
|
|
|
|
|
,const char **argv)
|
|
|
|
|
/* --- session management functions --- */
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN
|
|
|
|
|
int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
|
|
|
|
{
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
|
|
|
|
|
,const char **argv)
|
|
|
|
|
PAM_EXTERN
|
|
|
|
|
int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
|
|
|
|
{
|
|
|
|
|
return PAM_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
@@ -177,22 +287,15 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
|
|
|
|
|
/* end of module definition */
|
|
|
|
|
|
|
|
|
|
#ifdef PAM_STATIC
|
|
|
|
|
|
|
|
|
|
/* static module data */
|
|
|
|
|
|
|
|
|
|
struct pam_module _pam_passphrase_modstruct = {
|
|
|
|
|
"pam_sscs",
|
|
|
|
|
"pam_micasa",
|
|
|
|
|
pam_sm_authenticate,
|
|
|
|
|
pam_sm_setcred,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL
|
|
|
|
|
pam_sm_acct_mgmt,
|
|
|
|
|
pam_sm_open_session,
|
|
|
|
|
pam_sm_close_session,
|
|
|
|
|
#if 0
|
|
|
|
|
pam_sm_chauthtok
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|