- Added the functionality to handle change password in PAM system

This commit is contained in:
Rajasekaran Nagarajan 2006-09-26 05:03:03 +00:00
parent 06000507be
commit f4bf118742
6 changed files with 304 additions and 161 deletions

View File

@ -2,6 +2,7 @@ VER_1.0
{ {
global: global:
pam_sm_authenticate; pam_sm_authenticate;
pam_sm_chauthtok;
pam_sm_setcred; pam_sm_setcred;
pam_sm_acct_mgmt; pam_sm_acct_mgmt;
pam_sm_open_session; pam_sm_open_session;

View File

@ -2,6 +2,7 @@ VER_1.0
{ {
global: global:
pam_sm_authenticate; pam_sm_authenticate;
pam_sm_chauthtok;
pam_sm_setcred; pam_sm_setcred;
pam_sm_acct_mgmt; pam_sm_acct_mgmt;
pam_sm_open_session; pam_sm_open_session;

View File

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

View File

@ -20,57 +20,60 @@
* *
***********************************************************************/ ***********************************************************************/
/* /*
pam_sscs.h pam_sscs.h
*/ */
#ifndef _PAM_SSCS_H #ifndef _PAM_SSCS_H
#define _PAM_SSCS_H #define _PAM_SSCS_H
#include <dlfcn.h> #include <dlfcn.h>
#include <security/_pam_types.h> #include <security/_pam_types.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <errno.h> #include <errno.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <unistd.h> #include <unistd.h>
#include <pwd.h> #include <pwd.h>
#include <micasa.h> #include <micasa.h>
extern void pam_sscs_log(int priority, const char *format,...); extern void pam_sscs_log(int priority, const char *format,...);
#define WORKSTATION_SECRET_ID "Desktop" #define WORKSTATION_SECRET_ID "Desktop"
#define WORKSTATION_SHARED_SECRET_ID "DefaultSharedSecret" #define WORKSTATION_SHARED_SECRET_ID "DefaultSharedSecret"
#define NSSCSIDK_LIB "libmicasa.so" #define NSSCSIDK_LIB "libmicasa.so"
#define NOVELL_CSSS_CONTEXT "NOVELL_CSSS_CONTEXT" #define NOVELL_CSSS_CONTEXT "NOVELL_CSSS_CONTEXT"
#ifdef DEBUG #define MICASAD_PID_SIZE 32
#define PRINT_FN_NAME pam_sscs_log(LOG_DEBUG,"In function : %s\n",__func__); #define MICASAD_PID_FILE "/var/run/micasad.pid"
#else
#define PRINT_FN_NAME #ifdef DEBUG
#endif #define PRINT_FN_NAME pam_sscs_log(LOG_DEBUG,"In function : %s\n",__func__);
#else
void* (*pNSSCSOpenSecretStoreCache) ( SSCS_SECRETSTORE_T* ssid, #define PRINT_FN_NAME
unsigned long ssFlags, #endif
SSCS_EXT_T *ext);
int (*pNSSCSCloseSecretStoreCache) ( void *context, void* (*pNSSCSOpenSecretStoreCache) ( SSCS_SECRETSTORE_T* ssid,
unsigned long ssFlags, unsigned long ssFlags,
SSCS_EXT_T *ext); SSCS_EXT_T *ext);
int (*pNSSCSSetCredential) ( unsigned long ssFlags, int (*pNSSCSCloseSecretStoreCache) ( void *context,
SSCS_SECRET_ID_T *appSecretID, unsigned long ssFlags,
SSCS_SECRET_ID_T *sharedSecretID, SSCS_EXT_T *ext);
int credentialType, int (*pNSSCSSetCredential) ( unsigned long ssFlags,
void *credential, SSCS_SECRET_ID_T *appSecretID,
SSCS_EXT_T *ext); SSCS_SECRET_ID_T *sharedSecretID,
int credentialType,
/* The structure to hold all the possible options void *credential,
* for this PAM module. SSCS_EXT_T *ext);
*/
typedef struct options_t /* The structure to hold all the possible options
{ * for this PAM module.
unsigned int debug; */
}Options; typedef struct options_t
{
#endif unsigned int debug;
}Options;
#endif

View File

@ -1,24 +1,57 @@
#!/bin/bash #!/bin/bash
# Adding CASA pam entries to pam files. # Adding CASA pam entries to pam files.
rm -f *.rpmsave rm -f *.rpmsave
for file in "/etc/pam.d/login" "/etc/pam.d/sshd" "/etc/pam.d/xdm" "/etc/pam.d/gdm" "/etc/pam.d/kdm"
prefix="/etc/pam.d"
for auth_file in "$prefix/login" "$prefix/sshd" "$prefix/xdm" "$prefix/gdm" "$prefix/kdm"
do do
if [ -f $file ] if [ -f $auth_file ]
then then
sed -i '/pam_micasa/d' $file sed -i '/pam_micasa/d' $auth_file
var=`grep pam_unix2.so $file`
entry=`echo -e "auth\t required\tpam_micasa.so"` auth_entry=`echo -e "auth\t required\tpam_micasa.so"`
if [ "$var" != "" ]
var1=`grep ^auth.*required.*pam_unix2.so $auth_file`
if [ "$var1" != "" ]
then then
sed -i "/^auth.*required.*pam_unix2.so/a$entry" $file sed -i "/^auth.*required.*pam_unix2.so/a$auth_entry" $auth_file
continue continue
fi fi
var2=`grep common-auth $file`
var2=`grep ^auth.*include.*common-auth $auth_file`
if [ "$var2" != "" ] if [ "$var2" != "" ]
then then
sed -i "/^auth.*include.*common-auth/a$entry" $file sed -i "/^auth.*include.*common-auth/a$auth_entry" $auth_file
continue continue
fi fi
sed -i "0,/^auth/s/^\(auth.*\)/\1\n$entry/" $file
sed -i "0,/^auth/s/^\(auth.*\)/\1\n$auth_entry/" $auth_file
fi fi
done done
for password_file in "$prefix/passwd" "$prefix/gnome-passwd"
do
if [ -f $password_file ]
then
sed -i '/pam_micasa/d' $password_file
passwd_entry=`echo -e "password required\tpam_micasa.so"`
var1=`grep ^password.*required.*pam_unix2.so $password_file`
if [ "$var1" != "" ]
then
sed -i "/^password.*required.*pam_unix2.so/a$passwd_entry" $password_file
continue
fi
var2=`grep ^password.*include.*common-password $password_file`
if [ "$var2" != "" ]
then
sed -i "/^password.*include.*common-password/a$passwd_entry" $password_file
continue
fi
sed -i "0,/^password/s/^\(password.*\)/\1\n$passwd_entry/" $password_file
fi
done

View File

@ -1,6 +1,8 @@
#!/bin/bash #!/bin/bash
# Remove the CASA pam entries from pam files. # Remove the CASA pam entries from pam files.
for pam_file in "/etc/pam.d/login" "/etc/pam.d/sshd" "/etc/pam.d/xdm" "/etc/pam.d/gdm" "/etc/pam.d/kdm"
prefix="/etc/pam.d"
for pam_file in "$prefix/login" "$prefix/sshd" "$prefix/xdm" "$prefix/gdm" "$prefix/kdm" "$prefix/passwd" "$prefix/gnome-passwd"
do do
if [ -f $pam_file ] if [ -f $pam_file ]
then then