PVOID LsaNssOpen( PCSTR pszName, PCSTR pszDomain, int mode, PSTR pszOptions ) { DWORD dwError = LW_ERROR_SUCCESS; PLSA_PAM_CONFIG pConfig = NULL; dwError = LsaPamGetConfig(&pConfig); BAIL_ON_LSA_ERROR(dwError); LsaPamSetLogLevel(pConfig->dwLogLevel); LSA_LOG_PAM_DEBUG( "Open called for '%s' with options '%s'", pszName, pszOptions); LsaNssClearState(&gNssState); dwError = LwAllocateString( pszName, &gNssState.pszRegistryName); BAIL_ON_LSA_ERROR(dwError); if (!strcasecmp(pszOptions, "debug")) { LsaPamSetLogLevel(LSA_PAM_LOG_LEVEL_DEBUG); } cleanup: LSA_LOG_PAM_DEBUG("Open finishing with code %u", dwError); if (pConfig) { LsaPamFreeConfig(pConfig); } if (dwError != LW_ERROR_SUCCESS) { LsaNssMapErrorCode(dwError, &errno); return NULL; } else { return &gNssState; } 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; }
int pam_sm_close_session( pam_handle_t* pamh, int flags, int argc, const char** argv ) { DWORD dwError = 0; PPAMCONTEXT pPamContext = NULL; PSTR pszLoginId = NULL; HANDLE hLsaConnection = (HANDLE)NULL; PLSA_PAM_CONFIG pConfig = NULL; dwError = LsaPamGetConfig(&pConfig); BAIL_ON_LSA_ERROR(dwError); LsaPamSetLogLevel(pConfig->dwLogLevel); LSA_LOG_PAM_DEBUG("pam_sm_close_session::begin"); dwError = LsaPamGetContext( pamh, flags, argc, argv, &pPamContext); BAIL_ON_LSA_ERROR(dwError); dwError = LsaPamGetLoginId( pamh, pPamContext, &pszLoginId, FALSE); BAIL_ON_LSA_ERROR(dwError); if (pszLoginId == NULL) { dwError = LW_ERROR_NO_SUCH_USER; BAIL_ON_LSA_ERROR(dwError); } 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 = LsaCloseSession( hLsaConnection, pszLoginId); BAIL_ON_LSA_ERROR(dwError); dwError = LsaPamNotifyUserLogoff( 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); LSA_LOG_PAM_DEBUG("pam_sm_close_session::end"); return LsaPamOpenPamFilterCloseSession( LsaPamMapErrorCode(dwError, pPamContext)); error: if ((dwError == LW_ERROR_NO_SUCH_USER) || (dwError == LW_ERROR_NOT_HANDLED)) { LSA_LOG_PAM_WARNING("pam_sm_close_session error [error code:%u]", dwError); } else { LSA_LOG_PAM_ERROR("pam_sm_close_session error [error code:%u]", dwError); } goto cleanup; }
/* * This is where we check if the password expired. * If the password is correct, but has expired, we return * PAM_NEW_AUTHTOK_REQD instead of PAM_SUCCESS */ int pam_sm_acct_mgmt( pam_handle_t* pamh, int flags, int argc, const char** argv ) { DWORD dwError = 0; PPAMCONTEXT pPamContext = NULL; HANDLE hLsaConnection = (HANDLE)NULL; PLSA_USER_INFO_2 pUserInfo = NULL; DWORD dwUserInfoLevel = 2; PSTR pszLoginId = NULL; PLSA_PAM_CONFIG pConfig = NULL; int iPamError = 0; PSTR pszExpireDone; LSA_LOG_PAM_DEBUG("pam_sm_acct_mgmt::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); 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 = LsaCheckUserInList( hLsaConnection, pszLoginId, NULL); if (dwError && dwError != LW_ERROR_NO_SUCH_USER) { if (dwError == LW_ERROR_NO_SUCH_USER) { BAIL_ON_LSA_ERROR(dwError); } LSA_LOG_PAM_ERROR("User %s is denied access because they are not in the 'require membership of' list", LSA_SAFE_LOG_STRING(pszLoginId)); if (!LW_IS_NULL_OR_EMPTY_STR(pConfig->pszAccessDeniedMessage)) { LsaPamConverse(pamh, pConfig->pszAccessDeniedMessage, PAM_TEXT_INFO, NULL); } } BAIL_ON_LSA_ERROR(dwError); dwError = LsaValidateUser( hLsaConnection, pszLoginId, NULL); if (dwError == LW_ERROR_PASSWORD_EXPIRED) { dwError = 0; pPamContext->bPasswordExpired = TRUE; } BAIL_ON_LSA_ERROR(dwError); if (pPamContext->bPasswordExpired) { // If during pam_sm_authenticate, // we detected that the password expired, // we handle it here if (!pPamContext->bPasswordMessageShown) { LsaPamConverse( pamh, "Your password has expired", PAM_ERROR_MSG, NULL); pPamContext->bPasswordMessageShown = TRUE; } dwError = LW_ERROR_PASSWORD_EXPIRED; BAIL_ON_LSA_ERROR(dwError); } iPamError = pam_get_data( pamh, PAM_LSASS_EXPIRE_WARNING_DONE, (PAM_GET_DATA_TYPE)&pszExpireDone); if (iPamError == PAM_NO_MODULE_DATA) { dwError = LsaFindUserByName( hLsaConnection, pszLoginId, dwUserInfoLevel, (PVOID*)&pUserInfo); BAIL_ON_LSA_ERROR(dwError); if (pUserInfo->bPromptPasswordChange == TRUE && pUserInfo->bPasswordExpired == FALSE && pUserInfo->bPasswordNeverExpires == FALSE) { CHAR szMessage[512]; switch (pUserInfo->dwDaysToPasswordExpiry) { case 0: sprintf(szMessage, "Your password will expire today\n"); break; case 1: sprintf(szMessage, "Your password will expire in 1 day\n"); break; default: sprintf(szMessage, "Your password will expire in %u days\n", pUserInfo->dwDaysToPasswordExpiry); break; } LsaPamConverse(pamh, szMessage, PAM_TEXT_INFO, NULL); } dwError = LsaPamSetDataString( pamh, PAM_LSASS_EXPIRE_WARNING_DONE, "TRUE"); BAIL_ON_LSA_ERROR(dwError); } cleanup: if (pUserInfo) { LsaFreeUserInfo(dwUserInfoLevel, (PVOID)pUserInfo); } if (hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); } if (pConfig) { LsaPamFreeConfig(pConfig); } LW_SAFE_FREE_STRING(pszLoginId); LSA_LOG_PAM_DEBUG("pam_sm_acct_mgmt::end"); return LsaPamOpenPamFilterAcctMgmt( LsaPamMapErrorCode(dwError, pPamContext)); error: if (dwError == LW_ERROR_NO_SUCH_USER || dwError == LW_ERROR_NOT_HANDLED) { LSA_LOG_PAM_WARNING("pam_sm_acct_mgmt failed [login:%s][error code:%u]", LSA_SAFE_LOG_STRING(pszLoginId), dwError); } else { LSA_LOG_PAM_ERROR("pam_sm_acct_mgmt failed [login:%s][error code:%u]", LSA_SAFE_LOG_STRING(pszLoginId), dwError); if (pszLoginId && !strcmp(pszLoginId, "root")) { dwError = LW_ERROR_NO_SUCH_USER; LSA_LOG_PAM_ERROR("Converting error to %u for root", dwError); } } goto cleanup; }