private void updateCacheFromLdap() throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException, PwmUnrecoverableException { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "beginning process to updating user cache records from ldap"); if (status != STATUS.OPEN) { return; } cancelFlag = false; reportStatus = new ReportStatusInfo(settings.getSettingsHash()); reportStatus.setInProgress(true); reportStatus.setStartDate(new Date()); try { final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers()); reportStatus.setTotal(allUsers.size()); while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) { final Date startUpdateTime = new Date(); final UserIdentity userIdentity = allUsers.poll(); try { if (updateCachedRecordFromLdap(userIdentity)) { reportStatus.setUpdated(reportStatus.getUpdated() + 1); } } catch (Exception e) { String errorMsg = "error while updating report cache for " + userIdentity.toString() + ", cause: "; errorMsg += e instanceof PwmException ? ((PwmException) e).getErrorInformation().toDebugStr() : e.getMessage(); final ErrorInformation errorInformation; errorInformation = new ErrorInformation(PwmError.ERROR_REPORTING_ERROR, errorMsg); LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, errorInformation.toDebugStr()); reportStatus.setLastError(errorInformation); reportStatus.setErrors(reportStatus.getErrors() + 1); } reportStatus.setCount(reportStatus.getCount() + 1); reportStatus.getEventRateMeter().markEvents(1); final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime); if (settings.isAutoCalcRest()) { avgTracker.addSample(totalUpdateTime.getTotalMilliseconds()); Helper.pause(avgTracker.avgAsLong()); } else { Helper.pause(settings.getRestTime().getTotalMilliseconds()); } } if (cancelFlag) { reportStatus.setLastError( new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "report cancelled by operator")); } } finally { reportStatus.setFinishDate(new Date()); reportStatus.setInProgress(false); } LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "update user cache process completed: " + JsonUtil.serialize(reportStatus)); }
public UserCacheRecord next() { try { UserCacheRecord returnBean = null; while (returnBean == null && this.storageKeyIterator.hasNext()) { UserCacheService.StorageKey key = this.storageKeyIterator.next(); returnBean = userCacheService.readStorageKey(key); if (returnBean != null) { if (returnBean.getCacheTimestamp() == null) { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "purging record due to missing cache timestamp: " + JsonUtil.serialize(returnBean)); userCacheService.removeStorageKey(key); } else if (TimeDuration.fromCurrent(returnBean.getCacheTimestamp()) .isLongerThan(settings.getMaxCacheAge())) { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "purging record due to old age timestamp: " + JsonUtil.serialize(returnBean)); userCacheService.removeStorageKey(key); } else { return returnBean; } } } } catch (LocalDBException e) { throw new IllegalStateException( "unexpected iterator traversal error while reading LocalDB: " + e.getMessage()); } return null; }
@Override public void run() { try { initTempData(); } catch (LocalDBException | PwmUnrecoverableException e) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "error during initialization: " + e.getMessage()); status = STATUS.CLOSED; return; } final long secondsUntilNextDredge = settings.getJobOffsetSeconds() + TimeDuration.fromCurrent(Helper.nextZuluZeroTime()).getTotalSeconds(); executorService.scheduleAtFixedRate( new DredgeTask(), secondsUntilNextDredge, TimeDuration.DAY.getTotalSeconds(), TimeUnit.SECONDS); executorService.scheduleAtFixedRate( new RolloverTask(), secondsUntilNextDredge + 1, TimeDuration.DAY.getTotalSeconds(), TimeUnit.SECONDS); executorService.submit(new RolloverTask()); }
private void restBrowseLdap(final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean) throws IOException, ServletException, PwmUnrecoverableException { final StoredConfigurationImpl storedConfiguration = StoredConfigurationImpl.copy(configGuideBean.getStoredConfiguration()); if (configGuideBean.getStep() == STEP.LDAP_ADMIN) { storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE_KEY, null); storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE_KEY, null); } final Date startTime = new Date(); final Map<String, String> inputMap = pwmRequest.readBodyAsJsonStringMap(PwmHttpRequestWrapper.Flag.BypassValidation); final String profile = inputMap.get("profile"); final String dn = inputMap.containsKey("dn") ? inputMap.get("dn") : ""; final LdapBrowser ldapBrowser = new LdapBrowser(storedConfiguration); final LdapBrowser.LdapBrowseResult result = ldapBrowser.doBrowse(profile, dn); ldapBrowser.close(); LOGGER.trace( pwmRequest, "performed ldapBrowse operation in " + TimeDuration.fromCurrent(startTime).asCompactString() + ", result=" + JsonUtil.serialize(result)); pwmRequest.outputJsonResult(new RestResultBean(result)); }
@Override void closeConnection(final Connection connection) throws SQLException { if (aggressiveCompact) { CallableStatement statement = null; try { LOCK.writeLock().lock(); final java.util.Date start = new java.util.Date(); LOGGER.trace("beginning shutdown compact"); statement = dbConnection.prepareCall("SHUTDOWN COMPACT"); statement.execute(); LOGGER.trace( "completed shutdown compact in " + TimeDuration.fromCurrent(start).asCompactString()); } catch (SQLException ex) { LOGGER.error("error during shutdown compact: " + ex.getMessage()); } finally { close(statement); LOCK.writeLock().unlock(); } } try { connection.close(); if (driver != null) { DriverManager.deregisterDriver(driver); driver = null; } } catch (Exception e) { LOGGER.error("error during H2 shutdown: " + e.getMessage()); } }
public static PwmPasswordPolicy readPasswordPolicyForUser( final PwmApplication pwmApplication, final SessionLabel pwmSession, final UserIdentity userIdentity, final ChaiUser theUser, final Locale locale) throws PwmUnrecoverableException { final long startTime = System.currentTimeMillis(); final PasswordPolicySource ppSource = PasswordPolicySource.valueOf( pwmApplication.getConfig().readSettingAsString(PwmSetting.PASSWORD_POLICY_SOURCE)); final PwmPasswordPolicy returnPolicy; switch (ppSource) { case MERGE: final PwmPasswordPolicy pwmPolicy = determineConfiguredPolicyProfileForUser( pwmApplication, pwmSession, userIdentity, locale); final PwmPasswordPolicy userPolicy = readLdapPasswordPolicy(pwmApplication, theUser); LOGGER.trace( pwmSession, "read user policy for '" + theUser.getEntryDN() + "', policy: " + userPolicy.toString()); returnPolicy = pwmPolicy.merge(userPolicy); LOGGER.debug( pwmSession, "merged user password policy of '" + theUser.getEntryDN() + "' with PWM configured policy: " + returnPolicy.toString()); break; case LDAP: returnPolicy = readLdapPasswordPolicy(pwmApplication, theUser); LOGGER.debug( pwmSession, "discovered assigned password policy for " + theUser.getEntryDN() + " " + returnPolicy.toString()); break; case PWM: returnPolicy = determineConfiguredPolicyProfileForUser( pwmApplication, pwmSession, userIdentity, locale); break; default: throw new IllegalStateException("unknown policy source defined: " + ppSource.name()); } LOGGER.trace( pwmSession, "readPasswordPolicyForUser completed in " + TimeDuration.fromCurrent(startTime).asCompactString()); return returnPolicy; }
@Override void doCommand() throws Exception { final PwmApplication pwmApplication = cliEnvironment.getPwmApplication(); final File outputFile = (File) cliEnvironment.getOptions().get(CliParameters.REQUIRED_NEW_OUTPUT_FILE.getName()); Helper.pause(2000); final long startTime = System.currentTimeMillis(); final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmApplication, SessionLabel.SYSTEM_LABEL); final UserSearchEngine.SearchConfiguration searchConfiguration = new UserSearchEngine.SearchConfiguration(); searchConfiguration.setEnableValueEscaping(false); searchConfiguration.setUsername("*"); final String systemRecordDelimiter = System.getProperty("line.separator"); final Writer writer = new BufferedWriter(new PrintWriter(outputFile, PwmConstants.DEFAULT_CHARSET.toString())); final Map<UserIdentity, Map<String, String>> results = userSearchEngine.performMultiUserSearch( searchConfiguration, Integer.MAX_VALUE, Collections.<String>emptyList()); out( "searching " + results.size() + " users for stored responses to write to " + outputFile.getAbsolutePath() + "...."); int counter = 0; for (final UserIdentity identity : results.keySet()) { final ChaiUser user = pwmApplication.getProxiedChaiUser(identity); final ResponseSet responseSet = pwmApplication.getCrService().readUserResponseSet(null, identity, user); if (responseSet != null) { counter++; out("found responses for '" + user + "', writing to output."); final RestChallengesServer.JsonChallengesData outputData = new RestChallengesServer.JsonChallengesData(); outputData.challenges = responseSet.asChallengeBeans(true); outputData.helpdeskChallenges = responseSet.asHelpdeskChallengeBeans(true); outputData.minimumRandoms = responseSet.getChallengeSet().minimumResponses(); outputData.username = identity.toDelimitedKey(); writer.write(JsonUtil.serialize(outputData)); writer.write(systemRecordDelimiter); } else { out("skipping '" + user.toString() + "', no stored responses."); } } writer.close(); out( "output complete, " + counter + " responses exported in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
public void clear() throws LocalDBException, PwmUnrecoverableException { final Date startTime = new Date(); LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL, "clearing cached report data"); if (userCacheService != null) { userCacheService.clear(); } summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays()); reportStatus = new ReportStatusInfo(settings.getSettingsHash()); saveTempData(); LOGGER.info( PwmConstants.REPORTING_SESSION_LABEL, "finished clearing report " + TimeDuration.fromCurrent(startTime).asCompactString()); }
private void initServices() throws PwmUnrecoverableException { for (final Class<? extends PwmService> serviceClass : PWM_SERVICE_CLASSES) { final Date startTime = new Date(); final PwmService newServiceInstance; try { final Object newInstance = serviceClass.newInstance(); newServiceInstance = (PwmService) newInstance; } catch (Exception e) { final String errorMsg = "unexpected error instantiating service class '" + serviceClass.getName() + "', error: " + e.toString(); LOGGER.fatal(errorMsg, e); throw new PwmUnrecoverableException( new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg)); } try { LOGGER.debug("initializing service " + serviceClass.getName()); newServiceInstance.init(this); LOGGER.debug( "completed initialization of service " + serviceClass.getName() + " in " + TimeDuration.fromCurrent(startTime).asCompactString() + ", status=" + newServiceInstance.status()); } catch (PwmException e) { LOGGER.warn( "error instantiating service class '" + serviceClass.getName() + "', service will remain unavailable, error: " + e.getMessage()); } catch (Exception e) { String errorMsg = "unexpected error instantiating service class '" + serviceClass.getName() + "', cannot load, error: " + e.getMessage(); if (e.getCause() != null) { errorMsg += ", cause: " + e.getCause(); } LOGGER.fatal(errorMsg); throw new PwmUnrecoverableException( new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg)); } pwmServices.put(serviceClass, newServiceInstance); } }
private LocalDBLoggerSettings( final int maxEvents, final TimeDuration maxAge, final Set<Flag> flags, final int maxBufferSize, final TimeDuration maxBufferWaitTime, final int maxTrimSize) { this.maxEvents = maxEvents < 1 ? 0 : Math.max(MINIMUM_MAXIMUM_EVENTS, maxEvents); this.maxAge = maxAge == null || maxAge.isShorterThan(MINIMUM_MAX_AGE) ? MINIMUM_MAX_AGE : maxAge; this.flags = flags == null ? Collections.<Flag>emptySet() : Collections.unmodifiableSet(flags); this.maxBufferSize = maxBufferSize; this.maxBufferWaitTime = maxBufferWaitTime; this.maxTrimSize = maxTrimSize; }
public int outputStatsToCsv( final OutputStream outputStream, final Locale locale, final boolean includeHeader) throws IOException { LOGGER.trace("beginning output stats to csv process"); final Date startTime = new Date(); final StatisticsManager statsManger = pwmApplication.getStatisticsManager(); final CSVPrinter csvPrinter = Helper.makeCsvPrinter(outputStream); if (includeHeader) { final List<String> headers = new ArrayList<>(); headers.add("KEY"); headers.add("YEAR"); headers.add("DAY"); for (Statistic stat : Statistic.values()) { headers.add(stat.getLabel(locale)); } csvPrinter.printRecord(headers); } int counter = 0; final Map<StatisticsManager.DailyKey, String> keys = statsManger.getAvailableKeys(PwmConstants.DEFAULT_LOCALE); for (final StatisticsManager.DailyKey loopKey : keys.keySet()) { counter++; final StatisticsBundle bundle = statsManger.getStatBundleForKey(loopKey.toString()); final List<String> lineOutput = new ArrayList<>(); lineOutput.add(loopKey.toString()); lineOutput.add(String.valueOf(loopKey.year)); lineOutput.add(String.valueOf(loopKey.day)); for (final Statistic stat : Statistic.values()) { lineOutput.add(bundle.getStatistic(stat)); } csvPrinter.printRecord(lineOutput); } csvPrinter.flush(); LOGGER.trace( "completed output stats to csv process; output " + counter + " records in " + TimeDuration.fromCurrent(startTime).asCompactString()); return counter; }
private void updateRestingCacheData() { final long startTime = System.currentTimeMillis(); int examinedRecords = 0; ClosableIterator<UserCacheRecord> iterator = null; try { LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL, "checking size of stored cache records"); final int totalRecords = userCacheService.size(); LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "beginning cache review process of " + totalRecords + " records"); iterator = iterator(); Date lastLogOutputTime = new Date(); while (iterator.hasNext() && status == STATUS.OPEN) { final UserCacheRecord record = iterator.next(); // (purge routine is embedded in next(); if (summaryData != null && record != null) { summaryData.update(record); } examinedRecords++; if (TimeDuration.fromCurrent(lastLogOutputTime).isLongerThan(30, TimeUnit.SECONDS)) { final TimeDuration progressDuration = TimeDuration.fromCurrent(startTime); LOGGER.trace( PwmConstants.REPORTING_SESSION_LABEL, "cache review process in progress, examined " + examinedRecords + " records in " + progressDuration.asCompactString()); lastLogOutputTime = new Date(); } } final TimeDuration totalTime = TimeDuration.fromCurrent(startTime); LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "completed cache review process of " + examinedRecords + " cached report records in " + totalTime.asCompactString()); } finally { if (iterator != null) { iterator.close(); } } }
private static Map<String, Object> makeClientData( final PwmApplication pwmApplication, final PwmSession pwmSession, final HttpServletRequest request, final HttpServletResponse response, final String pageUrl) throws ChaiUnavailableException, PwmUnrecoverableException { final Configuration config = pwmApplication.getConfig(); final TreeMap<String, Object> settingMap = new TreeMap<>(); settingMap.put( "client.ajaxTypingTimeout", Integer.parseInt(config.readAppProperty(AppProperty.CLIENT_AJAX_TYPING_TIMEOUT))); settingMap.put( "client.ajaxTypingWait", Integer.parseInt(config.readAppProperty(AppProperty.CLIENT_AJAX_TYPING_WAIT))); settingMap.put( "client.activityMaxEpsRate", Integer.parseInt(config.readAppProperty(AppProperty.CLIENT_ACTIVITY_MAX_EPS_RATE))); settingMap.put( "client.js.enableHtml5Dialog", Boolean.parseBoolean(config.readAppProperty(AppProperty.CLIENT_JS_ENABLE_HTML5DIALOG))); settingMap.put( "client.pwShowRevertTimeout", Integer.parseInt(config.readAppProperty(AppProperty.CLIENT_PW_SHOW_REVERT_TIMEOUT))); settingMap.put( "enableIdleTimeout", config.readSettingAsBoolean(PwmSetting.DISPLAY_IDLE_TIMEOUT)); settingMap.put( "pageLeaveNotice", config.readSettingAsLong(PwmSetting.SECURITY_PAGE_LEAVE_NOTICE_TIMEOUT)); settingMap.put( "setting-showHidePasswordFields", pwmApplication .getConfig() .readSettingAsBoolean( password.pwm.config.PwmSetting.DISPLAY_SHOW_HIDE_PASSWORD_FIELDS)); settingMap.put("setting-displayEula", PwmConstants.ENABLE_EULA_DISPLAY); settingMap.put( "setting-showStrengthMeter", config.readSettingAsBoolean(PwmSetting.PASSWORD_SHOW_STRENGTH_METER)); { long idleSeconds = config.readSettingAsLong(PwmSetting.IDLE_TIMEOUT_SECONDS); if (pageUrl == null || pageUrl.isEmpty()) { LOGGER.warn(pwmSession, "request to /client data did not incliude pageUrl"); } else { try { final PwmURL pwmURL = new PwmURL(new URI(pageUrl), request.getContextPath()); final TimeDuration maxIdleTime = IdleTimeoutCalculator.idleTimeoutForRequest(pwmURL, pwmApplication, pwmSession); idleSeconds = maxIdleTime.getTotalSeconds(); } catch (Exception e) { LOGGER.error( pwmSession, "error determining idle timeout time for request: " + e.getMessage()); } } settingMap.put("MaxInactiveInterval", idleSeconds); } settingMap.put("paramName.locale", config.readAppProperty(AppProperty.HTTP_PARAM_NAME_LOCALE)); settingMap.put("startupTime", pwmApplication.getStartupTime()); settingMap.put("applicationMode", pwmApplication.getApplicationMode()); final String contextPath = request.getContextPath(); settingMap.put("url-context", contextPath); settingMap.put( "url-logout", contextPath + PwmServletDefinition.Logout.servletUrl() + "?idle=true"); settingMap.put("url-command", contextPath + PwmServletDefinition.Command.servletUrl()); settingMap.put( "url-resources", contextPath + "/public/resources" + pwmApplication.getResourceServletService().getResourceNonce()); settingMap.put("url-restservice", contextPath + "/public/rest"); { String passwordGuideText = pwmApplication .getConfig() .readSettingAsLocalizedString( PwmSetting.DISPLAY_PASSWORD_GUIDE_TEXT, pwmSession.getSessionStateBean().getLocale()); final MacroMachine macroMachine = pwmSession.getSessionManager().getMacroMachine(pwmApplication); passwordGuideText = macroMachine.expandMacros(passwordGuideText); settingMap.put("passwordGuideText", passwordGuideText); } { final List<String> formTypeOptions = new ArrayList<>(); for (final FormConfiguration.Type type : FormConfiguration.Type.values()) { formTypeOptions.add(type.toString()); } settingMap.put("formTypeOptions", formTypeOptions); } { final List<String> actionTypeOptions = new ArrayList<>(); for (final ActionConfiguration.Type type : ActionConfiguration.Type.values()) { actionTypeOptions.add(type.toString()); } settingMap.put("actionTypeOptions", actionTypeOptions); } { final List<String> epsTypes = new ArrayList<>(); for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) { epsTypes.add(loopEpsType.toString()); } settingMap.put("epsTypes", epsTypes); } { final List<String> epsDurations = new ArrayList<>(); for (final Statistic.EpsDuration loopEpsDuration : Statistic.EpsDuration.values()) { epsDurations.add(loopEpsDuration.toString()); } settingMap.put("epsDurations", epsDurations); } { final Map<String, String> localeInfo = new TreeMap<>(); final Map<String, String> localeDisplayNames = new TreeMap<>(); final Map<String, String> localeFlags = new TreeMap<>(); for (final Locale locale : pwmApplication.getConfig().getKnownLocales()) { final String flagCode = pwmApplication.getConfig().getKnownLocaleFlagMap().get(locale); localeFlags.put(locale.toString(), flagCode); localeInfo.put( locale.toString(), locale.getDisplayName() + " - " + locale.getDisplayLanguage(locale)); localeDisplayNames.put(locale.toString(), locale.getDisplayLanguage()); } settingMap.put("localeInfo", localeInfo); settingMap.put("localeDisplayNames", localeDisplayNames); settingMap.put("localeFlags", localeFlags); settingMap.put("defaultLocale", PwmConstants.DEFAULT_LOCALE.toString()); } if (pwmApplication .getConfig() .readSettingAsEnum(PwmSetting.LDAP_SELECTABLE_CONTEXT_MODE, SelectableContextMode.class) != SelectableContextMode.NONE) { final Map<String, Map<String, String>> ldapProfiles = new LinkedHashMap<>(); for (final String ldapProfile : pwmApplication.getConfig().getLdapProfiles().keySet()) { final Map<String, String> contexts = pwmApplication.getConfig().getLdapProfiles().get(ldapProfile).getLoginContexts(); ldapProfiles.put(ldapProfile, contexts); } settingMap.put("ldapProfiles", ldapProfiles); } return settingMap; }
public int compareTo(final Object o) { final TimeDuration td = (TimeDuration) o; final long otherMS = td.getTotalMilliseconds(); return (ms == otherMS ? 0 : (ms < otherMS ? -1 : 1)); }
public TimeDuration subtract(final TimeDuration duration) { return new TimeDuration( Math.abs(this.getTotalMilliseconds() - duration.getTotalMilliseconds())); }
private void init(final PwmApplication pwmApplication, final long maxAgeMs) { status = STATUS.OPENING; final long startTime = System.currentTimeMillis(); try { checkDbVersion(); } catch (Exception e) { LOGGER.error("error checking db version", e); status = STATUS.CLOSED; return; } try { final String oldestEntryStr = localDB.get(META_DB, KEY_OLDEST_ENTRY); if (oldestEntryStr == null || oldestEntryStr.length() < 1) { oldestEntry = 0; LOGGER.trace("no oldestEntry timestamp stored, will rescan"); } else { oldestEntry = Long.parseLong(oldestEntryStr); LOGGER.trace( "oldest timestamp loaded from localDB, age is " + TimeDuration.fromCurrent(oldestEntry).asCompactString()); } } catch (LocalDBException e) { LOGGER.error( "unexpected error loading oldest-entry meta record, will remain closed: " + e.getMessage(), e); status = STATUS.CLOSED; return; } try { final int size = localDB.size(WORDS_DB); final StringBuilder sb = new StringBuilder(); sb.append("open with ").append(size).append(" words ("); sb.append(new TimeDuration(System.currentTimeMillis(), startTime).asCompactString()) .append(")"); sb.append(", maxAgeMs=").append(new TimeDuration(maxAgeMs).asCompactString()); sb.append(", oldestEntry=") .append(new TimeDuration(System.currentTimeMillis(), oldestEntry).asCompactString()); LOGGER.info(sb.toString()); } catch (LocalDBException e) { LOGGER.error( "unexpected error examining size of DB, will remain closed: " + e.getMessage(), e); status = STATUS.CLOSED; return; } status = STATUS.OPEN; // populateFromWordlist(); //only used for debugging!!! if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING || pwmApplication.getApplicationMode() == PwmApplication.MODE.CONFIGURATION) { long frequencyMs = maxAgeMs > MAX_CLEANER_FREQUENCY ? MAX_CLEANER_FREQUENCY : maxAgeMs; frequencyMs = frequencyMs < MIN_CLEANER_FREQUENCY ? MIN_CLEANER_FREQUENCY : frequencyMs; LOGGER.debug( "scheduling cleaner task to run once every " + new TimeDuration(frequencyMs).asCompactString()); final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer"; cleanerTimer = new Timer(threadName, true); cleanerTimer.schedule(new CleanerTask(), 1000, frequencyMs); } }
public TimeDuration add(final TimeDuration duration) { return new TimeDuration(this.getTotalMilliseconds() + duration.getTotalMilliseconds()); }
@Override void doCommand() throws Exception { final PwmApplication pwmApplication = cliEnvironment.getPwmApplication(); final File inputFile = (File) cliEnvironment.getOptions().get(CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName()); final BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream(inputFile), PwmConstants.DEFAULT_CHARSET.toString())); out("importing stored responses from " + inputFile.getAbsolutePath() + "...."); int counter = 0; String line; final long startTime = System.currentTimeMillis(); while ((line = reader.readLine()) != null) { counter++; final RestChallengesServer.JsonChallengesData inputData; inputData = JsonUtil.deserialize(line, RestChallengesServer.JsonChallengesData.class); final UserIdentity userIdentity = UserIdentity.fromDelimitedKey(inputData.username); final ChaiUser user = pwmApplication.getProxiedChaiUser(userIdentity); if (user.isValid()) { out("writing responses to user '" + user.getEntryDN() + "'"); try { final ChallengeProfile challengeProfile = pwmApplication .getCrService() .readUserChallengeProfile( null, userIdentity, user, PwmPasswordPolicy.defaultPolicy(), PwmConstants.DEFAULT_LOCALE); final ChallengeSet challengeSet = challengeProfile.getChallengeSet(); final String userGuid = LdapOperationsHelper.readLdapGuidValue(pwmApplication, null, userIdentity, false); final ResponseInfoBean responseInfoBean = inputData.toResponseInfoBean( PwmConstants.DEFAULT_LOCALE, challengeSet.getIdentifier()); pwmApplication.getCrService().writeResponses(user, userGuid, responseInfoBean); } catch (Exception e) { out( "error writing responses to user '" + user.getEntryDN() + "', error: " + e.getMessage()); return; } } else { out("user '" + user.getEntryDN() + "' is not a valid userDN"); return; } } out( "output complete, " + counter + " responses imported in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
private void reduceWordDB() throws LocalDBException { if (localDB == null || localDB.status() != LocalDB.Status.OPEN) { return; } final long oldestEntryAge = System.currentTimeMillis() - oldestEntry; if (oldestEntryAge < settings.maxAgeMs) { LOGGER.debug( "skipping wordDB reduce operation, eldestEntry=" + TimeDuration.asCompactString(oldestEntryAge) + ", maxAge=" + TimeDuration.asCompactString(settings.maxAgeMs)); return; } final long startTime = System.currentTimeMillis(); final int initialSize = size(); int removeCount = 0; long localOldestEntry = System.currentTimeMillis(); LOGGER.debug( "beginning wordDB reduce operation, examining " + initialSize + " words for entries older than " + TimeDuration.asCompactString(settings.maxAgeMs)); LocalDB.LocalDBIterator<String> keyIterator = null; try { keyIterator = localDB.iterator(WORDS_DB); while (status == STATUS.OPEN && keyIterator.hasNext()) { final String key = keyIterator.next(); final String value = localDB.get(WORDS_DB, key); final long timeStamp = Long.parseLong(value); final long entryAge = System.currentTimeMillis() - timeStamp; if (entryAge > settings.maxAgeMs) { localDB.remove(WORDS_DB, key); removeCount++; if (removeCount % 1000 == 0) { LOGGER.trace( "wordDB reduce operation in progress, removed=" + removeCount + ", total=" + (initialSize - removeCount)); } } else { localOldestEntry = timeStamp < localOldestEntry ? timeStamp : localOldestEntry; } sleeper.sleep(); } } finally { try { if (keyIterator != null) { keyIterator.close(); } } catch (Exception e) { LOGGER.warn("error returning LocalDB iterator: " + e.getMessage()); } } // update the oldest entry if (status == STATUS.OPEN) { oldestEntry = localOldestEntry; localDB.put(META_DB, KEY_OLDEST_ENTRY, Long.toString(oldestEntry)); } final StringBuilder sb = new StringBuilder(); sb.append("completed wordDB reduce operation"); sb.append(", removed=").append(removeCount); sb.append(", totalRemaining=").append(size()); sb.append(", oldestEntry=").append(TimeDuration.asCompactString(oldestEntry)); sb.append(" in ") .append(TimeDuration.asCompactString(System.currentTimeMillis() - startTime)); LOGGER.debug(sb.toString()); }
public List<HealthRecord> healthCheck() { if (status == PwmService.STATUS.CLOSED) { return Collections.emptyList(); } final List<HealthRecord> returnRecords = new ArrayList<>(); try { preOperationCheck(); } catch (DatabaseException e) { lastError = e.getErrorInformation(); returnRecords.add( new HealthRecord( HealthStatus.WARN, HealthTopic.Database, "Database server is not available: " + e.getErrorInformation().toDebugStr())); return returnRecords; } try { final Map<String, String> tempMap = new HashMap<>(); tempMap.put("instance", instanceID); tempMap.put("date", (new java.util.Date()).toString()); this.put( DatabaseTable.PWM_META, DatabaseAccessorImpl.KEY_TEST, JsonUtil.serializeMap(tempMap)); } catch (PwmException e) { returnRecords.add( new HealthRecord( HealthStatus.WARN, HealthTopic.Database, "Error writing to database: " + e.getErrorInformation().toDebugStr())); return returnRecords; } if (lastError != null) { final TimeDuration errorAge = TimeDuration.fromCurrent(lastError.getDate().getTime()); if (errorAge.isShorterThan(TimeDuration.HOUR)) { returnRecords.add( new HealthRecord( HealthStatus.CAUTION, HealthTopic.Database, "Database server was recently unavailable (" + errorAge.asLongString(PwmConstants.DEFAULT_LOCALE) + " ago at " + lastError.getDate().toString() + "): " + lastError.toDebugStr())); } } if (returnRecords.isEmpty()) { returnRecords.add( new HealthRecord( HealthStatus.GOOD, HealthTopic.Database, "Database connection to " + this.dbConfiguration.getConnectionString() + " okay")); } return returnRecords; }
private void initialize(final boolean initLogging) throws PwmUnrecoverableException { final Date startTime = new Date(); // initialize log4j if (initLogging) { final String log4jFileName = configuration.readSettingAsString(PwmSetting.EVENTS_JAVA_LOG4JCONFIG_FILE); final File log4jFile = Helper.figureFilepath(log4jFileName, applicationPath); final String consoleLevel, fileLevel; switch (getApplicationMode()) { case ERROR: case NEW: consoleLevel = PwmLogLevel.TRACE.toString(); fileLevel = PwmLogLevel.TRACE.toString(); break; default: consoleLevel = configuration.readSettingAsString(PwmSetting.EVENTS_JAVA_STDOUT_LEVEL); fileLevel = configuration.readSettingAsString(PwmSetting.EVENTS_FILE_LEVEL); break; } PwmLogManager.initializeLogger( this, configuration, log4jFile, consoleLevel, applicationPath, fileLevel); switch (getApplicationMode()) { case RUNNING: break; case ERROR: LOGGER.fatal( "starting up in ERROR mode! Check log or health check information for cause"); break; default: LOGGER.trace( "setting log level to TRACE because application mode is " + getApplicationMode()); break; } } LOGGER.info( "initializing, application mode=" + getApplicationMode() + ", applicationPath=" + (applicationPath == null ? "null" : applicationPath.getAbsolutePath()) + ", configurationFile=" + (configurationFile == null ? "null" : configurationFile.getAbsolutePath())); this.localDB = Initializer.initializeLocalDB(this); this.localDBLogger = PwmLogManager.initializeLocalDBLogger(this); // log the loaded configuration LOGGER.info("configuration load completed"); // read the pwm servlet instance id instanceID = fetchInstanceID(localDB, this); LOGGER.info("using '" + getInstanceID() + "' for instance's ID (instanceID)"); // read the pwm installation date installTime = fetchInstallDate(startupTime); LOGGER.debug( "this application instance first installed on " + PwmConstants.DEFAULT_DATETIME_FORMAT.format(installTime)); initServices(); final TimeDuration totalTime = TimeDuration.fromCurrent(startTime); LOGGER.info( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " open for bidness! (" + totalTime.asCompactString() + ")"); StatisticsManager.incrementStat(this, Statistic.PWM_STARTUPS); LOGGER.debug( "buildTime=" + PwmConstants.BUILD_TIME + ", javaLocale=" + Locale.getDefault() + ", DefaultLocale=" + PwmConstants.DEFAULT_LOCALE); final Thread postInitThread = new Thread() { @Override public void run() { postInitTasks(); } }; postInitThread.setDaemon(true); postInitThread.setName(Helper.makeThreadName(this, PwmApplication.class)); postInitThread.start(); }
private void postInitTasks() { final Date startTime = new Date(); LOGGER.debug("loaded configuration: \n" + configuration.toDebugString()); // detect if config has been modified since previous startup try { final String previousHash = readAppAttribute(AppAttribute.CONFIG_HASH); final String currentHash = configuration.configurationHash(); if (previousHash == null || !previousHash.equals(currentHash)) { writeAppAttribute(AppAttribute.CONFIG_HASH, currentHash); LOGGER.warn( "configuration checksum does not match previously seen checksum, configuration has been modified since last startup"); if (this.getAuditManager() != null) { final String modifyMessage = "configuration was modified directly (not using ConfigEditor UI)"; this.getAuditManager() .submit( SystemAuditRecord.create( AuditEvent.MODIFY_CONFIGURATION, modifyMessage, this.getInstanceID())); } } } catch (Exception e) { LOGGER.debug( "unable to detect if configuration has been modified since previous startup: " + e.getMessage()); } if (this.getConfig() != null) { final Map<AppProperty, String> nonDefaultProperties = getConfig().readAllNonDefaultAppProperties(); if (nonDefaultProperties != null && !nonDefaultProperties.isEmpty()) { final Map<String, String> tempMap = new LinkedHashMap<>(); for (final AppProperty loopProperty : nonDefaultProperties.keySet()) { tempMap.put(loopProperty.getKey(), nonDefaultProperties.get(loopProperty)); } LOGGER.trace( "non-default app properties read from configuration: " + JsonUtil.serializeMap(tempMap)); } else { LOGGER.trace("no non-default app properties in configuration"); } } // send system audit event final SystemAuditRecord auditRecord = SystemAuditRecord.create(AuditEvent.STARTUP, null, getInstanceID()); try { getAuditManager().submit(auditRecord); } catch (PwmException e) { LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord)); } try { Map<PwmAboutProperty, String> infoMap = Helper.makeInfoBean(this); LOGGER.trace("application info: " + JsonUtil.serializeMap(infoMap)); } catch (Exception e) { LOGGER.error("error generating about application bean: " + e.getMessage()); } try { this.getIntruderManager() .clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME); } catch (Exception e) { LOGGER.debug( "error while clearing configmanager-intruder-username from intruder table: " + e.getMessage()); } LOGGER.trace( "completed post init tasks in " + TimeDuration.fromCurrent(startTime).asCompactString()); }
private boolean updateCachedRecordFromLdap( final UserIdentity userIdentity, final UserInfoBean userInfoBean, final UserCacheService.StorageKey storageKey) throws ChaiUnavailableException, PwmUnrecoverableException, LocalDBException { final UserCacheRecord userCacheRecord = userCacheService.readStorageKey(storageKey); TimeDuration cacheAge = null; if (userCacheRecord != null && userCacheRecord.getCacheTimestamp() != null) { cacheAge = TimeDuration.fromCurrent(userCacheRecord.getCacheTimestamp()); } boolean updateCache = false; if (userInfoBean != null) { updateCache = true; } else { if (cacheAge == null) { LOGGER.trace( PwmConstants.REPORTING_SESSION_LABEL, "stored cache for " + userIdentity + " is missing cache storage timestamp, will update"); updateCache = true; } else if (cacheAge.isLongerThan(settings.getMinCacheAge())) { LOGGER.trace( PwmConstants.REPORTING_SESSION_LABEL, "stored cache for " + userIdentity + " is " + cacheAge.asCompactString() + " old, will update"); updateCache = true; } } if (updateCache) { if (userCacheRecord != null) { if (summaryData != null && summaryData.getEpoch() != null && summaryData.getEpoch().equals(userCacheRecord.getSummaryEpoch())) { summaryData.remove(userCacheRecord); } } final UserInfoBean newUserBean; if (userInfoBean != null) { newUserBean = userInfoBean; } else { newUserBean = new UserInfoBean(); final UserStatusReader.Settings readerSettings = new UserStatusReader.Settings(); readerSettings.setSkipReportUpdate(true); final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final UserStatusReader userStatusReader = new UserStatusReader( pwmApplication, PwmConstants.REPORTING_SESSION_LABEL, readerSettings); userStatusReader.populateUserInfoBean( newUserBean, PwmConstants.DEFAULT_LOCALE, userIdentity, chaiProvider); } final UserCacheRecord newUserCacheRecord = userCacheService.updateUserCache(newUserBean); if (summaryData != null && summaryData.getEpoch() != null && newUserCacheRecord != null) { if (!summaryData.getEpoch().equals(newUserCacheRecord.getSummaryEpoch())) { newUserCacheRecord.setSummaryEpoch(summaryData.getEpoch()); userCacheService.store(newUserCacheRecord); } summaryData.update(newUserCacheRecord); } } return updateCache; }
private AuthenticationResult authenticateUserImpl(final PasswordData password) throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException { if (startTime == null) { startTime = new Date(); } log( PwmLogLevel.DEBUG, "preparing to authenticate user using authenticationType=" + this.requestedAuthType + " using strategy " + this.strategy); final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager(); final IntruderManager intruderManager = pwmApplication.getIntruderManager(); intruderManager.convenience().checkUserIdentity(userIdentity); intruderManager.check(RecordType.ADDRESS, sessionLabel.getSrcAddress()); boolean allowBindAsUser = true; if (strategy == AuthenticationStrategy.ADMIN_PROXY) { allowBindAsUser = false; } if (allowBindAsUser) { try { testCredentials(userIdentity, password); } catch (PwmOperationalException e) { boolean permitAuthDespiteError = false; final ChaiProvider.DIRECTORY_VENDOR vendor = pwmApplication .getProxyChaiProvider(userIdentity.getLdapProfileID()) .getDirectoryVendor(); if (PwmError.PASSWORD_NEW_PASSWORD_REQUIRED == e.getError()) { if (vendor == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) { if (pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_REQUIRE_NEW_PWD)) { log( PwmLogLevel.INFO, "auth bind failed, but will allow login due to 'must change password on next login AD error', error: " + e.getErrorInformation().toDebugStr()); allowBindAsUser = false; permitAuthDespiteError = true; } } else if (vendor == ChaiProvider.DIRECTORY_VENDOR.ORACLE_DS) { if (pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.ORACLE_DS_ALLOW_AUTH_REQUIRE_NEW_PWD)) { log( PwmLogLevel.INFO, "auth bind failed, but will allow login due to 'pwdReset' user attribute, error: " + e.getErrorInformation().toDebugStr()); allowBindAsUser = false; permitAuthDespiteError = true; } } } else if (PwmError.PASSWORD_EXPIRED == e.getError()) { // handle ad case where password is expired if (vendor == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) { if (pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_REQUIRE_NEW_PWD)) { if (!pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_EXPIRED)) { throw e; } log( PwmLogLevel.INFO, "auth bind failed, but will allow login due to 'password expired AD error', error: " + e.getErrorInformation().toDebugStr()); allowBindAsUser = false; permitAuthDespiteError = true; } } } if (!permitAuthDespiteError) { // auth failed, presumably due to wrong password. statisticsManager.incrementValue(Statistic.AUTHENTICATION_FAILURES); throw e; } } } else { // verify user is not account disabled AuthenticationUtility.checkIfUserEligibleToAuthentication(pwmApplication, userIdentity); } statisticsManager.incrementValue(Statistic.AUTHENTICATIONS); statisticsManager.updateEps(Statistic.EpsType.AUTHENTICATION, 1); statisticsManager.updateAverageValue( Statistic.AVG_AUTHENTICATION_TIME, TimeDuration.fromCurrent(startTime).getTotalMilliseconds()); final AuthenticationType returnAuthType; if (!allowBindAsUser) { returnAuthType = AuthenticationType.AUTH_BIND_INHIBIT; } else { if (requestedAuthType == null) { returnAuthType = AuthenticationType.AUTHENTICATED; } else { if (requestedAuthType == AuthenticationType.AUTH_WITHOUT_PASSWORD) { returnAuthType = AuthenticationType.AUTHENTICATED; } else if (requestedAuthType == AuthenticationType.AUTH_FROM_PUBLIC_MODULE) { returnAuthType = AuthenticationType.AUTH_FROM_PUBLIC_MODULE; } else { returnAuthType = requestedAuthType; } } } final boolean useProxy = determineIfLdapProxyNeeded(returnAuthType, password); final ChaiProvider returnProvider = useProxy ? makeProxyProvider() : userProvider; final AuthenticationResult authenticationResult = new AuthenticationResult(returnProvider, returnAuthType, password); final StringBuilder debugMsg = new StringBuilder(); debugMsg.append("successful ldap authentication for ").append(userIdentity); debugMsg.append(" (").append(TimeDuration.fromCurrent(startTime).asCompactString()).append(")"); debugMsg.append(" type: ").append(returnAuthType).append(", using strategy ").append(strategy); debugMsg.append(", using proxy connection: ").append(useProxy); debugMsg .append(", returning bind dn: ") .append( returnProvider == null ? "none" : returnProvider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN)); log(PwmLogLevel.INFO, debugMsg); pwmApplication .getAuditManager() .submit( pwmApplication .getAuditManager() .createUserAuditRecord( AuditEvent.AUTHENTICATE, this.userIdentity, makeAuditLogMessage(returnAuthType), sessionLabel.getSrcAddress(), sessionLabel.getSrcHostname())); return authenticationResult; }