Bug 143940. Prevent buffer overflow on usernames and passwords that are longer than buffers.
This commit is contained in:
		| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user