Bug 143940. Prevent buffer overflow on usernames and passwords that are longer than buffers.

This commit is contained in:
Jim Norman 2006-02-13 15:58:09 +00:00
parent 78997d2777
commit ec458809d0

View File

@ -5,7 +5,7 @@
* 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.
* 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
@ -28,13 +28,11 @@
* 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.
* 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.
* In the session stack, the functionality of the module is to do
* a Close of the user's SESSION Keychain.
*
*/
@ -52,7 +50,7 @@
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
const char **argv)
{
int retVal = 0, rc = 0;
int retVal = 0;
const char *user = NULL;
const char *wkstnPasswd = NULL;
@ -60,10 +58,6 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
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.
*/
@ -78,7 +72,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
pam_get_item(pamh,PAM_AUTHTOK,(const void**)&wkstnPasswd);
passwdEntry = getpwnam(user);
/* SSCS 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.
*/
if(passwdEntry)
@ -88,12 +82,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
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;
@ -115,22 +104,35 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
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;
// 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,
retVal = (*pNSSCSSetCredential) (0,
&secretID,
NULL,
SSCS_CRED_TYPE_BASIC_F,
&basicCredential,NULL);
&basicCredential,
NULL);
if( retVal != 0)
{
pam_sscs_log( LOG_ERR,"Setting the default credential failed.Errcode = %d\n",retVal);
@ -157,7 +159,6 @@ PAM_EXTERN
int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
PRINT_FN_NAME
return PAM_SUCCESS;
}
@ -170,72 +171,6 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc
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;
}