Bug 143940. Prevent buffer overflow on usernames and passwords that are longer than buffers.
This commit is contained in:
parent
78997d2777
commit
ec458809d0
@ -1,42 +1,40 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* License as published by the Free Software Foundation; version 2.1
|
* 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,
|
* This library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* Library Lesser General Public License for more details.
|
* Library Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, Novell, Inc.
|
* License along with this library; if not, Novell, Inc.
|
||||||
*
|
*
|
||||||
* To contact Novell about this file by physical or electronic mail,
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
* you may find current contact information at www.novell.com.
|
* you may find current contact information at www.novell.com.
|
||||||
*
|
*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/* miCASAd PAM module
|
/* miCASAd PAM module
|
||||||
*
|
*
|
||||||
* This is a PAM module which is used to capture the workstation
|
* This is a PAM module which is used to capture the workstation
|
||||||
* user/password and store the same in miCASAd .
|
* user/password and store the same in miCASAd .
|
||||||
* This would be placed in login/xdm/gdm/kdm/sshd PAM configuration files.
|
* 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
|
* This module needs to be present before any other PAM module which
|
||||||
* requires the services of miCASAd. It needs to be present in both
|
* requires the services of miCASAd. It needs to be present
|
||||||
* the auth and session stacks of the PAM configuration files.
|
* the auth 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 session stack, the functionality of the module is to do
|
*
|
||||||
* a Close of the user's SESSION Keychain.
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "pam_sscs.h"
|
#include "pam_sscs.h"
|
||||||
@ -50,193 +48,130 @@
|
|||||||
#include <security/_pam_macros.h>
|
#include <security/_pam_macros.h>
|
||||||
|
|
||||||
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
|
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
|
||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
int retVal = 0, rc = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
const char *user = NULL;
|
const char *user = NULL;
|
||||||
const char *wkstnPasswd = NULL;
|
const char *wkstnPasswd = NULL;
|
||||||
|
|
||||||
uid_t saved_uid = geteuid();
|
uid_t saved_uid = geteuid();
|
||||||
struct passwd *passwdEntry = NULL;
|
struct passwd *passwdEntry = NULL;
|
||||||
|
|
||||||
struct pam_message msg[1], *pmsg[1];
|
/*
|
||||||
struct pam_response *resp;
|
* Get the username first.
|
||||||
struct pam_conv *conv;
|
*/
|
||||||
|
retVal = pam_get_user(pamh, &user, NULL);
|
||||||
|
|
||||||
/*
|
if ( PAM_SUCCESS != retVal )
|
||||||
* Get the username first.
|
{
|
||||||
*/
|
pam_sscs_log( LOG_ERR, "pam_get_user returned error: %d - %s\n",retVal,pam_strerror(pamh,retVal));
|
||||||
retVal = pam_get_user(pamh, &user, NULL);
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if ( PAM_SUCCESS != retVal )
|
pam_get_item(pamh,PAM_AUTHTOK,(const void**)&wkstnPasswd);
|
||||||
{
|
passwdEntry = getpwnam(user);
|
||||||
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);
|
/* CASA determines the client uid using the SO_PEERCRED socket option.
|
||||||
passwdEntry = getpwnam(user);
|
* Hence the euid is temporarily modified to that of the user logging in.
|
||||||
|
*/
|
||||||
|
if(passwdEntry)
|
||||||
|
{
|
||||||
|
seteuid( passwdEntry->pw_uid );
|
||||||
|
|
||||||
/* SSCS determines the client uid using the SO_PEERCRED socket option.
|
do
|
||||||
* Hence the euid is temporarily modified to that of the user logging in.
|
{
|
||||||
*/
|
char *error = NULL;
|
||||||
if(passwdEntry)
|
SSCS_SECRET_ID_T secretID = {0};
|
||||||
{
|
SSCS_BASIC_CREDENTIAL basicCredential;
|
||||||
seteuid( passwdEntry->pw_uid );
|
int credType;
|
||||||
|
|
||||||
do
|
void *nsscsIdkHandle = dlopen(NSSCSIDK_LIB,RTLD_NOW);
|
||||||
{
|
if( NULL == nsscsIdkHandle )
|
||||||
char *error = NULL;
|
{
|
||||||
void *ssContext = NULL;
|
pam_sscs_log(LOG_ERR,"Unable to open %s\n",NSSCSIDK_LIB);
|
||||||
SSCS_SECRETSTORE_T ssId = {0};
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SSCS_SECRET_ID_T secretID = {0};
|
pNSSCSSetCredential = dlsym( nsscsIdkHandle,
|
||||||
SSCS_SECRET_ID_T sharedSecretID = {0};
|
"miCASASetCredential");
|
||||||
|
if( (error = dlerror()) != NULL )
|
||||||
|
{
|
||||||
|
pam_sscs_log(LOG_ERR,"Unable to find miCASASetCredential symbol.- %s\n",error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SSCS_BASIC_CREDENTIAL basicCredential;
|
secretID.len = strlen(WORKSTATION_SECRET_ID) + 1;
|
||||||
int credType;
|
strcpy(secretID.id,WORKSTATION_SECRET_ID);
|
||||||
|
|
||||||
void *nsscsIdkHandle = dlopen(NSSCSIDK_LIB,RTLD_NOW);
|
memset(&basicCredential,0,sizeof(basicCredential));
|
||||||
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)
|
if (user && wkstnPasswd)
|
||||||
{
|
{
|
||||||
basicCredential.unFlags = 0;
|
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);
|
strcpy(basicCredential.username,user);
|
||||||
basicCredential.unLen = strlen(user) + 1;
|
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);
|
strcpy(basicCredential.password,wkstnPasswd);
|
||||||
basicCredential.pwordLen = strlen(wkstnPasswd) + 1;
|
basicCredential.pwordLen = strlen(wkstnPasswd) + 1;
|
||||||
|
|
||||||
retVal = (*pNSSCSSetCredential) (0,&secretID,NULL,
|
retVal = (*pNSSCSSetCredential) (0,
|
||||||
SSCS_CRED_TYPE_BASIC_F,
|
&secretID,
|
||||||
&basicCredential,NULL);
|
NULL,
|
||||||
|
SSCS_CRED_TYPE_BASIC_F,
|
||||||
|
&basicCredential,
|
||||||
|
NULL);
|
||||||
if( retVal != 0)
|
if( retVal != 0)
|
||||||
{
|
{
|
||||||
pam_sscs_log( LOG_ERR,"Setting the default credential failed.Errcode = %d\n",retVal);
|
pam_sscs_log( LOG_ERR,"Setting the default credential failed.Errcode = %d\n",retVal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(0);
|
}while(0);
|
||||||
|
|
||||||
seteuid(saved_uid);
|
seteuid(saved_uid);
|
||||||
}
|
}
|
||||||
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 --- */
|
/* --- account management functions --- */
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
PRINT_FN_NAME
|
return PAM_SUCCESS;
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc
|
PAM_EXTERN int pam_sm_open_session(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_close_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 **argv)
|
||||||
{
|
{
|
||||||
const char *user = NULL;
|
return PAM_SUCCESS;
|
||||||
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 */
|
/* end of module definition */
|
||||||
@ -246,17 +181,17 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
|
|||||||
/* static module data */
|
/* static module data */
|
||||||
|
|
||||||
struct pam_module _pam_passphrase_modstruct = {
|
struct pam_module _pam_passphrase_modstruct = {
|
||||||
"pam_sscs",
|
"pam_sscs",
|
||||||
pam_sm_authenticate,
|
pam_sm_authenticate,
|
||||||
pam_sm_setcred,
|
pam_sm_setcred,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
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
|
#if 0
|
||||||
pam_sm_chauthtok
|
pam_sm_chauthtok
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user