diff options
author | Nadav Vinik <email@nadavvin.com> | 2010-10-25 16:08:20 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@novell.com> | 2010-10-25 16:08:20 +0100 |
commit | 617a1feae1ff04f6de6bfb91c3c5b05d709c03cb (patch) | |
tree | ccf14e7cf14ffb58c94caa57f9160f225c8c5683 /sal | |
parent | 7007c9943026a4106763a8f362c2314a6a46ec4a (diff) |
remove un-necessary pam usage
Diffstat (limited to 'sal')
-rw-r--r-- | sal/inc/osl/security.h | 7 | ||||
-rw-r--r-- | sal/osl/unx/security.c | 460 |
2 files changed, 14 insertions, 453 deletions
diff --git a/sal/inc/osl/security.h b/sal/inc/osl/security.h index d22f128c0..0fd27f5a8 100644 --- a/sal/inc/osl/security.h +++ b/sal/inc/osl/security.h @@ -35,8 +35,8 @@ extern "C" { #endif typedef enum { - osl_Security_E_None, - osl_Security_E_UserUnknown, + osl_Security_E_None, + osl_Security_E_UserUnknown, osl_Security_E_WrongPassword, osl_Security_E_Unknown, osl_Security_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM @@ -57,7 +57,8 @@ typedef void* oslSecurity; */ oslSecurity SAL_CALL osl_getCurrentSecurity(void); -/** Create a security handle for the denoted user. +/** Deprecated API + Create a security handle for the denoted user. Try to log in the user on the local system. @param strzUserName [in] denotes the name of the user to logg in. @param strPasswd [in] the password for this user. diff --git a/sal/osl/unx/security.c b/sal/osl/unx/security.c index 92bc432ce..0cc1072fc 100644 --- a/sal/osl/unx/security.c +++ b/sal/osl/unx/security.c @@ -47,12 +47,6 @@ #include "secimpl.h" -#ifndef NOPAM -#ifndef PAM_BINARY_MSG -#define PAM_BINARY_MSG 6 -#endif -#endif - static oslSecurityError SAL_CALL osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd, oslSecurity* pSecurity); @@ -141,311 +135,6 @@ oslSecurity SAL_CALL osl_getCurrentSecurity() } } - -#if defined LINUX && !defined NOPAM - -/* - * - * osl Routines for Pluggable Authentication Modules (PAM) - * tested with Linux-PAM 0.66 on Redhat-6.0 and - * Linux-PAM 0.64 on RedHat-5.2, - * XXX Will probably not run on PAM 0.59 or prior, since - * number of pam_response* responses has changed - * - */ - -#include <security/pam_appl.h> - -typedef struct { - char* name; - char* password; -} sal_PamData; - -typedef struct { - int (*pam_start)(const char *service_name, const char *user, - const struct pam_conv *pam_conversation, - pam_handle_t **pamh); - int (*pam_end) (pam_handle_t *pamh, int pam_status); - int (*pam_authenticate) (pam_handle_t *pamh, int flags); - int (*pam_acct_mgmt) (pam_handle_t *pamh, int flags); -} sal_PamModule; - -/* - * Implement a pam-conversation callback-routine, - * it just supply name and password instead of prompting the user. - * I guess that echo-off means 'ask for password' and echo-on means - * 'ask for user-name'. In fact I've never been asked anything else - * than the password - * XXX Please notice that if a pam-module does ask anything else, we - * are completely lost, and a pam-module is free to do so - * XXX - */ - -static int -osl_PamConversation (int num_msg, const struct pam_message **msgm, - struct pam_response **response, void *appdata_ptr) -{ - int i; - sal_Bool error; - sal_PamData *pam_data; - struct pam_response *p_reply; - - /* resource initialization */ - pam_data = (sal_PamData*) appdata_ptr; - p_reply = (struct pam_response *) calloc( num_msg, - sizeof(struct pam_response)); - if ( p_reply == NULL || pam_data == NULL ) - { - if ( p_reply != NULL ) - free ( p_reply ); - *response = NULL; - return PAM_CONV_ERR; - } - - /* pseudo dialog */ - error = sal_False; - for ( i = 0; i < num_msg ; i++ ) - { - switch ( msgm[ i ]->msg_style ) - { - case PAM_PROMPT_ECHO_OFF: - p_reply[ i ].resp_retcode = 0; - p_reply[ i ].resp = strdup( pam_data->password ); - break; - case PAM_PROMPT_ECHO_ON: - p_reply[ i ].resp_retcode = 0; - p_reply[ i ].resp = strdup( pam_data->name ); - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - case PAM_BINARY_PROMPT: - case PAM_BINARY_MSG: - p_reply[ i ].resp_retcode = 0; - p_reply[ i ].resp = NULL; - break; - default: - error = sal_True; - break; - } - } - - /* free resources on error */ - if ( error ) - { - for ( i = 0; i < num_msg ; i++ ) - if ( p_reply[ i ].resp ) - { - memset ( p_reply[ i ].resp, 0, - strlen( p_reply[ i ].resp ) ); - free ( p_reply[ i ].resp ); - } - free ( p_reply ); - - *response = NULL; - return PAM_CONV_ERR; - } - - /* well done */ - *response = p_reply; - return PAM_SUCCESS; -} - -#ifndef PAM_LINK -/* - * avoid linking against libpam.so, since it is not available on all systems, - * instead load-on-call, returns structure which holds pointer to - * pam-functions, - * library is never closed in case of success - */ - -static sal_PamModule* osl_getPAM() -{ - static sal_PamModule *pam_module = NULL; - static sal_Bool load_once = sal_False; - - if ( !load_once ) - { - /* get library-handle. cannot use osl-module, since - RTLD_GLOBAL is required for PAM-0.64 RH 5.2 - (but not for PAM-0.66 RH 6.0) */ - void *pam_hdl; - - pam_hdl = dlopen( "libpam.so.0", RTLD_GLOBAL | RTLD_LAZY ); - - if ( pam_hdl != NULL ) - pam_module = (sal_PamModule*)calloc( 1, sizeof(sal_PamModule) ); - - /* load functions */ - if ( pam_module != NULL ) - { - pam_module->pam_acct_mgmt = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_acct_mgmt" ); - pam_module->pam_authenticate - = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_authenticate" ); - pam_module->pam_end = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_end" ); - pam_module->pam_start = (int (*)(const char *, const char *, const struct pam_conv *, pam_handle_t **)) dlsym ( pam_hdl, "pam_start" ); - - /* free resources, if not completely successful */ - if ( (pam_module->pam_start == NULL) - || (pam_module->pam_end == NULL) - || (pam_module->pam_authenticate == NULL) - || (pam_module->pam_acct_mgmt == NULL) ) - { - free( pam_module ); - pam_module = NULL; - dlclose( pam_hdl ); - } - } - - /* never try again */ - load_once = sal_True; - } - - return pam_module; -} -#endif - -/* - * User Identification using PAM - */ - -static sal_Bool -osl_PamAuthentification( const sal_Char* name, const sal_Char* password ) -{ - sal_Bool success = sal_False; - -#ifndef PAM_LINK - sal_PamModule* pam_module; - - pam_module = osl_getPAM(); - if ( pam_module != NULL ) - { -#endif - pam_handle_t *pam_handle = NULL; - struct pam_conv pam_conversation; - sal_PamData pam_data; - - int return_value; - - pam_data.name = (char*) name; - pam_data.password = (char*) password; - - pam_conversation.conv = osl_PamConversation; - pam_conversation.appdata_ptr = (void*)(&pam_data); - -#ifndef PAM_LINK - return_value = pam_module->pam_start( "su", name, - &pam_conversation, &pam_handle); -#else - return_value = pam_start( "su", name, - &pam_conversation, &pam_handle); -#endif - if (return_value == PAM_SUCCESS ) -#ifndef PAM_LINK - return_value = pam_module->pam_authenticate(pam_handle, 0); -#else - return_value = pam_authenticate(pam_handle, 0); -#endif - if (return_value == PAM_SUCCESS ) -#ifndef PAM_LINK - return_value = pam_module->pam_acct_mgmt(pam_handle, 0); - pam_module->pam_end( pam_handle, return_value ); -#else - return_value = pam_acct_mgmt(pam_handle, 0); - pam_end( pam_handle, return_value ); -#endif - - success = (sal_Bool)(return_value == PAM_SUCCESS); -#ifndef PAM_LINK - } -#endif - - return success; -} - - -#ifndef CRYPT_LINK -/* dummy crypt, matches the interface of - crypt() but does not encrypt at all */ -static const sal_Char* SAL_CALL -osl_noCrypt ( const sal_Char *key, const sal_Char *salt ) -{ - (void) salt; /* unused */ - return key; -} - -/* load-on-call crypt library and crypt symbol */ -static void* SAL_CALL -osl_getCrypt() -{ - static char* (*crypt_sym)(const char*, const char*) = NULL; - static sal_Bool load_once = sal_False; - - if ( !load_once ) - { - void * crypt_library; - - crypt_library = dlopen( "libcrypt.so.1", RTLD_GLOBAL | RTLD_LAZY ); /* never closed */ - if ( crypt_library != NULL ) - crypt_sym = (char* (*)(const char *, const char *)) dlsym(crypt_library, "crypt" ); - if ( crypt_sym == NULL ) /* no libcrypt or libcrypt without crypt */ - crypt_sym = (char* (*)(const char *, const char *)) &osl_noCrypt; - - load_once = sal_True; - } - - return (void*)crypt_sym; -} - -/* replacement for crypt function for password encryption, uses either - strong encryption of dlopen'ed libcrypt.so.1 or dummy implementation - with no encryption. Objective target is to avoid linking against - libcrypt (not available on caldera open linux 2.2 #63822#) */ -static sal_Char* SAL_CALL -osl_dynamicCrypt ( const sal_Char *key, const sal_Char *salt ) -{ - char* (*dynamic_crypt)(char *, char *); - - dynamic_crypt = (char * (*)(char *, char *)) osl_getCrypt(); - - return dynamic_crypt( (sal_Char*)key, (sal_Char*)salt ); -} -#endif - -/* - * compare an encrypted and an unencrypted password for equality - * returns true if passwords are equal, false otherwise - * Note: uses crypt() and a mutex instead of crypt_r() since crypt_r needs - * more than 128KByte of external buffer for struct crypt_data - */ - -static sal_Bool SAL_CALL -osl_equalPasswords ( const sal_Char *pEncryptedPassword, const sal_Char *pPlainPassword ) -{ - static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER; - - sal_Bool success; - sal_Char salt[3]; - sal_Char *encrypted_plain; - - salt[0] = pEncryptedPassword[0]; - salt[1] = pEncryptedPassword[1]; - salt[2] = '\0'; - - pthread_mutex_lock(&crypt_mutex); - -#ifndef CRYPT_LINK - encrypted_plain = (sal_Char *)osl_dynamicCrypt( pPlainPassword, salt ); -#else - encrypted_plain = (sal_Char *)crypt( pPlainPassword, salt ); -#endif - success = (sal_Bool) (strcmp(pEncryptedPassword, encrypted_plain) == 0); - - pthread_mutex_unlock(&crypt_mutex); - - return success; -} - -#endif /* defined LINUX && !defined NOPAM */ oslSecurityError SAL_CALL osl_loginUser( rtl_uString *ustrUserName, rtl_uString *ustrPassword, @@ -457,10 +146,9 @@ oslSecurityError SAL_CALL osl_loginUser( rtl_String* strPassword=0; sal_Char* pszUserName=0; sal_Char* pszPassword=0; - + if ( ustrUserName != 0 ) { - rtl_uString2String( &strUserName, rtl_uString_getStr(ustrUserName), rtl_uString_getLength(ustrUserName), @@ -468,7 +156,7 @@ oslSecurityError SAL_CALL osl_loginUser( OUSTRING_TO_OSTRING_CVTFLAGS ); pszUserName = rtl_string_getStr(strUserName); } - + if ( ustrPassword != 0 ) { @@ -476,165 +164,37 @@ oslSecurityError SAL_CALL osl_loginUser( rtl_uString_getStr(ustrPassword), rtl_uString_getLength(ustrPassword), RTL_TEXTENCODING_UTF8, - OUSTRING_TO_OSTRING_CVTFLAGS ); + OUSTRING_TO_OSTRING_CVTFLAGS ); pszPassword = rtl_string_getStr(strPassword); } - - + + Error=osl_psz_loginUser(pszUserName,pszPassword,pSecurity); if ( strUserName != 0 ) - { + { rtl_string_release(strUserName); } - + if ( strPassword) { rtl_string_release(strPassword); } - - + + return Error; } - + static oslSecurityError SAL_CALL osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd, oslSecurity* pSecurity) { -#if defined NETBSD || defined SCO || defined AIX || defined FREEBSD || \ - defined MACOSX (void)pszUserName; (void)pszPasswd; (void)pSecurity; return osl_Security_E_None; - -#else - - oslSecurityError nError = osl_Security_E_Unknown; - oslSecurityImpl * p = NULL; - if (pszUserName != NULL && pszPasswd != NULL && pSecurity != NULL) { - /* get nis or normal password, should succeed for any known user, but - perhaps the password is wrong (i.e. 'x') if shadow passwords are in - use or authentication must be done by PAM */ - size_t n = 0; - int err = 0; - struct passwd * found = NULL; - for (;;) { - p = growSecurityImpl(p, &n); - if (p == NULL) { - break; - } - err = getpwnam_r( - pszUserName, &p->m_pPasswd, p->m_buffer, n, &found); - if (err != ERANGE) { - break; - } - } - if (p != NULL && err == 0) { - if (found == NULL) { - nError = osl_Security_E_UserUnknown; - } else { -#if defined LINUX && !defined NOPAM - /* only root is able to read the /etc/shadow passwd, a normal - user even can't read his own encrypted passwd */ - if (osl_equalPasswords(p->m_pPasswd.pw_passwd, pszPasswd) || - osl_PamAuthentification(pszUserName, pszPasswd)) - { - nError = osl_Security_E_None; - } else { - char buffer[1024]; - struct spwd result_buf; - struct spwd * pShadowPasswd; - buffer[0] = '\0'; - if (getspnam_r( - pszUserName, &result_buf, buffer, sizeof buffer, - &pShadowPasswd) == 0 && - pShadowPasswd != NULL) - { - nError = - osl_equalPasswords( - pShadowPasswd->sp_pwdp, pszPasswd) - ? osl_Security_E_None - : osl_Security_E_WrongPassword; - } else if (getuid() == 0) { - /* mfe: Try to verify the root-password via nis */ - if (getspnam_r( - "root", &result_buf, buffer, sizeof buffer, - &pShadowPasswd) == 0 && - pShadowPasswd != NULL && - osl_equalPasswords( - pShadowPasswd->sp_pwdp, pszPasswd)) - { - nError = osl_Security_E_None; - } else { - /* mfe: we can't get via nis (glibc2.0.x has bug in - getspnam_r) we try it with the normal getspnam */ - static pthread_mutex_t pwmutex = - PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&pwmutex); - pShadowPasswd = getspnam("root"); - pthread_mutex_unlock(&pwmutex); - nError = - ((pShadowPasswd != NULL && - osl_equalPasswords( - pShadowPasswd->sp_pwdp, pszPasswd)) || - osl_PamAuthentification("root", pszPasswd)) - ? osl_Security_E_None - : osl_Security_E_WrongPassword; - } - } - } -#else - char buffer[1024]; - struct spwd spwdStruct; - buffer[0] = '\0'; -#ifndef NEW_SHADOW_API - if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer) != NULL) -#else - if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer, NULL) == 0) -#endif - { - char salt[3]; - char * cryptPasswd; - strncpy(salt, spwdStruct.sp_pwdp, 2); - salt[2] = '\0'; - cryptPasswd = (char *) crypt(pszPasswd, salt); - if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) { - nError = osl_Security_E_None; - } else if (getuid() == 0 && -#ifndef NEW_SHADOW_API - (getspnam_r("root", &spwdStruct, buffer, sizeof buffer) != NULL)) -#else - (getspnam_r("root", &spwdStruct, buffer, sizeof buffer, NULL) == 0)) -#endif - { - /* if current process is running as root, allow to logon - as any other user */ - strncpy(salt, spwdStruct.sp_pwdp, 2); - salt[2] = '\0'; - cryptPasswd = (char *) crypt(pszPasswd, salt); - if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) { - nError = osl_Security_E_None; - } - } else { - nError = osl_Security_E_WrongPassword; - } - } -#endif - } - } - } - if (nError == osl_Security_E_None) { - *pSecurity = p; - } else { - deleteSecurityImpl(p); - *pSecurity = NULL; - } - return nError; - -#endif } oslSecurityError SAL_CALL osl_loginUserOnFileServer( |