- 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:
pam_sm_authenticate;
pam_sm_chauthtok;
pam_sm_setcred;
pam_sm_acct_mgmt;
pam_sm_open_session;

View File

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

View File

@ -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_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)
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

View File

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

View File

@ -1,24 +1,57 @@
#!/bin/bash
# Adding CASA pam entries to pam files.
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
if [ -f $file ]
if [ -f $auth_file ]
then
sed -i '/pam_micasa/d' $file
var=`grep pam_unix2.so $file`
entry=`echo -e "auth\t required\tpam_micasa.so"`
if [ "$var" != "" ]
sed -i '/pam_micasa/d' $auth_file
auth_entry=`echo -e "auth\t required\tpam_micasa.so"`
var1=`grep ^auth.*required.*pam_unix2.so $auth_file`
if [ "$var1" != "" ]
then
sed -i "/^auth.*required.*pam_unix2.so/a$entry" $file
sed -i "/^auth.*required.*pam_unix2.so/a$auth_entry" $auth_file
continue
fi
var2=`grep common-auth $file`
var2=`grep ^auth.*include.*common-auth $auth_file`
if [ "$var2" != "" ]
then
sed -i "/^auth.*include.*common-auth/a$entry" $file
sed -i "/^auth.*include.*common-auth/a$auth_entry" $auth_file
continue
fi
sed -i "0,/^auth/s/^\(auth.*\)/\1\n$entry/" $file
sed -i "0,/^auth/s/^\(auth.*\)/\1\n$auth_entry/" $auth_file
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
# 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
if [ -f $pam_file ]
then