diff --git a/login_capture/PAM/pam_sscs.c b/login_capture/PAM/pam_sscs.c index c3cbf7ac..359a3ec3 100644 --- a/login_capture/PAM/pam_sscs.c +++ b/login_capture/PAM/pam_sscs.c @@ -1,263 +1,198 @@ /*********************************************************************** - * - * Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, Novell, Inc. - * - * To contact Novell about this file by physical or electronic mail, - * you may find current contact information at www.novell.com. - * - ***********************************************************************/ +* +* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; version 2.1 +* of the License. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, Novell, Inc. +* +* To contact Novell about this file by physical or electronic mail, +* you may find current contact information at www.novell.com. +* +***********************************************************************/ -/* miCASAd PAM module - * - * This is a PAM module which is used to capture the workstation - * user/password and store the same in miCASAd . - * This would be placed in login/xdm/gdm/kdm/sshd PAM configuration files. - * - * This module needs to be present before any other PAM module which - * requires the services of miCASAd. It needs to be present in both - * the auth and session 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 session stack, the functionality of the module is to do - * a Close of the user's SESSION Keychain. - * - */ - - -#include "pam_sscs.h" - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION - -#include -#include -#include - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, - const char **argv) -{ - int retVal = 0, rc = 0; - - const char *user = NULL; - const char *wkstnPasswd = NULL; - - uid_t saved_uid = geteuid(); - struct passwd *passwdEntry = NULL; - - struct pam_message msg[1], *pmsg[1]; - struct pam_response *resp; - struct pam_conv *conv; - - /* - * Get the username first. - */ - 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 PAM_SUCCESS; - } - - pam_get_item(pamh,PAM_AUTHTOK,(const void**)&wkstnPasswd); - passwdEntry = getpwnam(user); - - /* SSCS 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 ); - - do - { - char *error = NULL; - void *ssContext = NULL; - SSCS_SECRETSTORE_T ssId = {0}; - - SSCS_SECRET_ID_T secretID = {0}; - SSCS_SECRET_ID_T sharedSecretID = {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; - } - - 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); - - sharedSecretID.len = strlen(WORKSTATION_SHARED_SECRET_ID) + 1; - strcpy(sharedSecretID.id,WORKSTATION_SHARED_SECRET_ID); - - memset(&basicCredential,0,sizeof(basicCredential)); - - if (user && wkstnPasswd) - { - basicCredential.unFlags = 0; - strcpy(basicCredential.username,user); - basicCredential.unLen = strlen(user) + 1; - 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); - } - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- account management functions --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - PRINT_FN_NAME - return PAM_SUCCESS; -} - -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) -{ - const char *user = NULL; - int retVal = 0; - uid_t saved_uid = geteuid(); - struct passwd *passwdEntry = NULL; - - PRINT_FN_NAME - - 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 PAM_SUCCESS; - } - - passwdEntry = getpwnam(user); - - seteuid( passwdEntry->pw_uid ); - - do - { - char *error = NULL; - void *ssContext = NULL; - SSCS_SECRETSTORE_T ssId = {0}; - - void *nsscsIdkHandle = dlopen(NSSCSIDK_LIB,RTLD_NOW); - if( NULL == nsscsIdkHandle ) - { - pam_sscs_log(LOG_ERR,"Unable to open %s\n",NSSCSIDK_LIB); - break; - } - - pNSSCSOpenSecretStoreCache = dlsym(nsscsIdkHandle, - "miCASAOpenSecretStoreCache"); - if( (error = dlerror()) != NULL ) - { - pam_sscs_log(LOG_ERR,"Unable to find miCASAOpenSecretStoreCache symbol. - %s\n",error); - break; - } - - pNSSCSCloseSecretStoreCache = dlsym(nsscsIdkHandle, - "miCASACloseSecretStoreCache"); - if( (error = dlerror()) != NULL ) - { - pam_sscs_log(LOG_ERR,"Unable to find miCASACloseSecretStoreCache symbol. - %s\n",error); - break; - } - strcpy(ssId.ssName, passwdEntry->pw_name); - ssId.version = NSSCS_VERSION_NUMBER; - - ssContext = (*pNSSCSOpenSecretStoreCache)(&ssId,0,NULL); - if( NULL == ssContext ) - { - pam_sscs_log( LOG_ERR,"Opening SecretStore for the user %s failed.\n",passwdEntry->pw_name); - break; - } - - retVal = (*pNSSCSCloseSecretStoreCache) (ssContext,0,NULL); - if( retVal != 0 ) - { - pam_sscs_log(LOG_ERR,"Closing SecretStore for the user %s failed.\n",passwdEntry->pw_name); - break; - } - - }while(0); - - seteuid(saved_uid); - return PAM_SUCCESS; -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_passphrase_modstruct = { - "pam_sscs", - 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 +/* miCASAd PAM module +* +* This is a PAM module which is used to capture the workstation +* user/password and store the same in miCASAd . +* This would be placed in login/xdm/gdm/kdm/sshd PAM configuration files. +* +* 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. +* +* In the auth stack, the functionality of the module is to store +* the workstation user/password in micasad. +* +*/ + + +#include "pam_sscs.h" + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION + +#include +#include +#include + +PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, + const char **argv) +{ + int retVal = 0; + + const char *user = NULL; + const char *wkstnPasswd = NULL; + + uid_t saved_uid = geteuid(); + struct passwd *passwdEntry = NULL; + + /* + * Get the username first. + */ + 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 PAM_SUCCESS; + } + + pam_get_item(pamh,PAM_AUTHTOK,(const void**)&wkstnPasswd); + passwdEntry = getpwnam(user); + + /* 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 ); + + 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; + } + + 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); + + memset(&basicCredential,0,sizeof(basicCredential)); + + 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(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); + } + return PAM_SUCCESS; +} + +PAM_EXTERN +int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc + ,const char **argv) +{ + return PAM_SUCCESS; +} + +/* --- account management functions --- */ + +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) +{ + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc + ,const char **argv) +{ + return PAM_SUCCESS; +} + +/* end of module definition */ + +#ifdef PAM_STATIC + +/* static module data */ + +struct pam_module _pam_passphrase_modstruct = { + "pam_sscs", + 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