/* * VerifyNullHandling * */ static DWORD VerifyNullHandling( HANDLE hLsaConnection ) { PCSTR pszTestDescription = "LsaOpenSession does not accept NULL login id."; PCSTR pszTestAPIs = "LsaOpenSession"; char szTestMsg[128] = { 0 }; DWORD dwLocalError = LW_ERROR_SUCCESS; DWORD dwError = LW_ERROR_SUCCESS; int bSessionIsOpen = 0; dwLocalError = LsaOpenSession(hLsaConnection, NULL); if ( dwLocalError == LW_ERROR_SUCCESS ) { bSessionIsOpen = 1; snprintf( szTestMsg, sizeof(szTestMsg), "LsaOpenSession did not return error for a NULL login id."); dwError = LW_ERROR_TEST_FAILED; goto error; } cleanup: if ( bSessionIsOpen ) { dwError = LsaCloseSession(hLsaConnection, NULL); bSessionIsOpen = 0; } LWT_LOG_TEST(szTestMsg); return dwError; error: goto cleanup; }
int pam_sm_open_session( pam_handle_t* pamh, int flags, int argc, const char** argv ) { DWORD dwError = 0; PPAMCONTEXT pPamContext = NULL; HANDLE hLsaConnection = (HANDLE)NULL; PSTR pszLoginId = NULL; PLSA_PAM_CONFIG pConfig = NULL; #ifdef HAVE_PAM_PUTENV PSTR pszSmartCardReader = NULL; PSTR pszSmartCardReaderEnv = NULL; #endif /* HAVE_PAM_PUTENV */ LSA_LOG_PAM_DEBUG("pam_sm_open_session::begin"); dwError = LsaPamGetConfig(&pConfig); BAIL_ON_LSA_ERROR(dwError); LsaPamSetLogLevel(pConfig->dwLogLevel); dwError = LsaPamGetContext( pamh, flags, argc, argv, &pPamContext); BAIL_ON_LSA_ERROR(dwError); dwError = LsaPamGetLoginId( pamh, pPamContext, &pszLoginId, TRUE); BAIL_ON_LSA_ERROR(dwError); #ifdef HAVE_PAM_PUTENV dwError = pam_get_data( pamh, PAM_LSASS_SMART_CARD_READER, (PAM_GET_DATA_TYPE)&pszSmartCardReader); /* pszSmartCardReader will be freed when the module is closed. */ if (dwError == PAM_SUCCESS && pszSmartCardReader != NULL) { dwError = LwAllocateStringPrintf( &pszSmartCardReaderEnv, "LW_SMART_CARD_READER=%s", pszSmartCardReader); BAIL_ON_LSA_ERROR(dwError); dwError = pam_putenv( pamh, pszSmartCardReaderEnv); BAIL_ON_LSA_ERROR(dwError); } #endif /* HAVE_PAM_PUTENV */ if (LsaShouldIgnoreUser(pszLoginId)) { LSA_LOG_PAM_DEBUG("By passing lsassd for local account"); dwError = LW_ERROR_NOT_HANDLED; BAIL_ON_LSA_ERROR(dwError); } dwError = LsaOpenServer(&hLsaConnection); BAIL_ON_LSA_ERROR(dwError); dwError = LsaOpenSession( hLsaConnection, pszLoginId); BAIL_ON_LSA_ERROR(dwError); if (pPamContext && pConfig->bLsaPamDisplayMOTD) { dwError = LsaPamDisplayMOTD( pamh, pPamContext); BAIL_ON_LSA_ERROR(dwError); } if (pPamContext && pPamContext->bOnlineLogon) { dwError = LsaPamNotifyUserLogon( pszLoginId); if (dwError == LW_ERROR_LOAD_LIBRARY_FAILED || dwError == LW_ERROR_LOOKUP_SYMBOL_FAILED ) { dwError = 0; } BAIL_ON_LSA_ERROR(dwError); } cleanup: if (hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); } if (pConfig) { LsaPamFreeConfig(pConfig); } LW_SAFE_FREE_STRING(pszLoginId); #ifdef HAVE_PAM_PUTENV LW_SAFE_FREE_STRING(pszSmartCardReaderEnv); #endif /* HAVE_PAM_PUTENV */ LSA_LOG_PAM_DEBUG("pam_sm_open_session::end"); return LsaPamOpenPamFilterOpenSession( LsaPamMapErrorCode(dwError, pPamContext)); error: if ((dwError == LW_ERROR_NO_SUCH_USER) || (dwError == LW_ERROR_NOT_HANDLED)) { LSA_LOG_PAM_WARNING("pam_sm_open_session failed [login:%s][error code: %u]", LSA_SAFE_LOG_STRING(pszLoginId), dwError); } else { LSA_LOG_PAM_ERROR("pam_sm_open_session failed [login:%s][error code: %u]", LSA_SAFE_LOG_STRING(pszLoginId), dwError); } goto cleanup; }
/* * CheckLsaOpenSession * */ static DWORD CheckLsaOpenSession( HANDLE hLsaConnection, PCSTR pszLoginId, PLWTUSER pUser ) { PCSTR pszTestDescription = "Home directory exists after call to LsaOpenSession for valid user."; PCSTR pszTestAPIs = "LsaOpenSession," "LsaCloseSession," "LsaCheckUserInList," "LsaAuthenticateUser"; char szTestMsg[128] = { 0 }; DWORD dwError = LW_ERROR_SUCCESS; int bSessionIsOpen = 0; snprintf(szTestMsg, sizeof(szTestMsg), "Session for %s", pszLoginId); dwError = LsaOpenSession(hLsaConnection, pszLoginId); if ( dwError ) goto error; bSessionIsOpen = 1; if ( !IsNullOrEmpty(pUser->pszUnixHomeDirectory) ) { struct stat statbuf; if ( stat(pUser->pszUnixHomeDirectory, &statbuf) < 0 ) { char buf[64]; snprintf( buf, sizeof(buf), ",could not stat %s", pUser->pszUnixHomeDirectory); Lwt_strcat(szTestMsg, sizeof(szTestMsg), buf); dwError = LW_ERROR_TEST_FAILED; goto error; } if ( !S_ISDIR(statbuf.st_mode) ) { Lwt_strcat( szTestMsg, sizeof(szTestMsg), ",home is not a directory."); dwError = LW_ERROR_TEST_FAILED; } if ( !IsNullOrEmpty(pUser->pszUnixUid) ) { if ( statbuf.st_uid != pUser->nUnixUid ) { Lwt_strcat( szTestMsg, sizeof(szTestMsg), ",uid doesn't match expected"); dwError = LW_ERROR_TEST_FAILED; } } } cleanup: if ( bSessionIsOpen ) { dwError = LsaCloseSession(hLsaConnection, pszLoginId); bSessionIsOpen = 0; } LWT_LOG_TEST(szTestMsg); return dwError; error: goto cleanup; }
int LsaNssAuthenticate( PSTR pszUser, PSTR pszResponse, int* pReenter, PSTR* ppszOutputMessage ) { int iError = 0; DWORD dwError = LW_ERROR_SUCCESS; PLSA_USER_INFO_0 pInfo = NULL; const DWORD dwInfoLevel = 0; PSTR pszMessage = NULL; PLSA_USER_INFO_2 pInfo2 = NULL; LSA_LOG_PAM_DEBUG("Lsass LAM authenticating user [%s]", pszUser? pszUser: "******"); dwError = LsaNssCommonEnsureConnected(&lsaConnection); BAIL_ON_LSA_ERROR(dwError); dwError = LsaNssFindUserByAixName( lsaConnection.hLsaConnection, pszUser, dwInfoLevel, (PVOID*)&pInfo); BAIL_ON_LSA_ERROR(dwError); dwError = LsaAuthenticateUser( lsaConnection.hLsaConnection, pInfo->pszName, pszResponse, &pszMessage); if (dwError == LW_ERROR_PASSWORD_EXPIRED) { // Double check that the user's password is marked as expired dwError = LsaFindUserByName( lsaConnection.hLsaConnection, pInfo->pszName, 2, (PVOID*)&pInfo2); BAIL_ON_LSA_ERROR(dwError); if (!pInfo2->bPasswordExpired) { // Something went wrong in lsassd -- don't let the user login dwError = LW_ERROR_PASSWORD_EXPIRED; } } BAIL_ON_LSA_ERROR(dwError); dwError = LsaCheckUserInList( lsaConnection.hLsaConnection, pInfo->pszName, NULL); BAIL_ON_LSA_ERROR(dwError); // Need to ensure that home directories are created. dwError = LsaOpenSession( lsaConnection.hLsaConnection, pInfo->pszName); BAIL_ON_LSA_ERROR(dwError); cleanup: if (ppszOutputMessage) { *ppszOutputMessage = pszMessage; } else { LW_SAFE_FREE_STRING(pszMessage); } if (pInfo != NULL) { LsaFreeUserInfo( dwInfoLevel, pInfo); } if (pInfo2 != NULL) { LsaFreeUserInfo( 2, pInfo2); } switch(dwError) { case LW_ERROR_SUCCESS: iError = AUTH_SUCCESS; break; case LW_ERROR_NOT_HANDLED: case LW_ERROR_NO_SUCH_USER: iError = AUTH_NOTFOUND; break; case LW_ERROR_ACCOUNT_EXPIRED: case LW_ERROR_ACCOUNT_DISABLED: case LW_ERROR_ACCOUNT_LOCKED: iError = AUTH_FAILURE; break; default: iError = AUTH_UNAVAIL; break; } LSA_LOG_PAM_DEBUG("Lsass LAM authenticate finishing with likewise code %u and LAM code %d", dwError, iError); return iError; error: LsaNssCommonCloseConnection(&lsaConnection); goto cleanup; }