private void doHealthChecks() { if (status != STATUS.OPEN) { return; } LOGGER.trace("beginning health check process"); final List<HealthRecord> newResults = new ArrayList<>(); for (final HealthChecker loopChecker : healthCheckers) { try { final List<HealthRecord> loopResults = loopChecker.doHealthCheck(pwmApplication); if (loopResults != null) { newResults.addAll(loopResults); } } catch (Exception e) { LOGGER.warn("unexpected error during healthCheck: " + e.getMessage(), e); } } for (final PwmService service : pwmApplication.getPwmServices()) { try { final List<HealthRecord> loopResults = service.healthCheck(); if (loopResults != null) { newResults.addAll(loopResults); } } catch (Exception e) { LOGGER.warn("unexpected error during healthCheck: " + e.getMessage(), e); } } final Set<HealthRecord> sortedRecordList = new TreeSet<>(); sortedRecordList.addAll(newResults); healthRecords = Collections.unmodifiableSet(sortedRecordList); lastHealthCheckDate = new Date(); LOGGER.trace("health check process completed"); }
public void shutdown() { LOGGER.warn("shutting down"); { // send system audit event final SystemAuditRecord auditRecord = SystemAuditRecord.create(AuditEvent.SHUTDOWN, null, getInstanceID()); try { getAuditManager().submit(auditRecord); } catch (PwmException e) { LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord)); } } { final List<Class> reverseServiceList = new ArrayList<Class>(PWM_SERVICE_CLASSES); Collections.reverse(reverseServiceList); for (final Class serviceClass : reverseServiceList) { if (pwmServices.containsKey(serviceClass)) { LOGGER.trace("closing service " + serviceClass.getName()); final PwmService loopService = pwmServices.get(serviceClass); LOGGER.trace("successfully closed service " + serviceClass.getName()); try { loopService.close(); } catch (Exception e) { LOGGER.error( "error closing " + loopService.getClass().getSimpleName() + ": " + e.getMessage(), e); } } } } if (localDBLogger != null) { try { localDBLogger.close(); } catch (Exception e) { LOGGER.error("error closing localDBLogger: " + e.getMessage(), e); } localDBLogger = null; } if (localDB != null) { try { localDB.close(); } catch (Exception e) { LOGGER.fatal("error closing localDB: " + e, e); } localDB = null; } LOGGER.info( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " closed for bidness, cya!"); }
static Set<TokenVerificationProgress.TokenChannel> determineTokenPhaseRequired( final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean, final UpdateAttributesProfile updateAttributesProfile) throws PwmUnrecoverableException { final Set<TokenVerificationProgress.TokenChannel> returnObj = new HashSet<>(); final Map<String, String> userFormData = updateProfileBean.getFormData(); Map<String, String> ldapData = null; if (updateAttributesProfile.readSettingAsBoolean( PwmSetting.UPDATE_PROFILE_EMAIL_VERIFICATION)) { final String emailAddressAttribute = pwmRequest.getConfig().readSettingAsString(PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE); if (userFormData.containsKey(emailAddressAttribute)) { ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile); if (userFormData.get(emailAddressAttribute) != null && !userFormData .get(emailAddressAttribute) .equalsIgnoreCase(ldapData.get(emailAddressAttribute))) { returnObj.add(TokenVerificationProgress.TokenChannel.EMAIL); } } else { LOGGER.warn( pwmRequest, "email verification enabled, but email attribute '" + emailAddressAttribute + "' is not in update form"); } } if (updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_SMS_VERIFICATION)) { final String phoneNumberAttribute = pwmRequest.getConfig().readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE); if (userFormData.containsKey(phoneNumberAttribute)) { if (ldapData == null) { ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile); } if (userFormData.get(phoneNumberAttribute) != null && !userFormData .get(phoneNumberAttribute) .equalsIgnoreCase(ldapData.get(phoneNumberAttribute))) { returnObj.add(TokenVerificationProgress.TokenChannel.SMS); } } else { LOGGER.warn( pwmRequest, "sms verification enabled, but phone attribute '" + phoneNumberAttribute + "' is not in update form"); } } return returnObj; }
public boolean containsWord(final String word) { if (status != STATUS.OPEN) { return false; } final String testWord = normalizeWord(word); if (testWord == null) { return false; } // final long startTime = System.currentTimeMillis(); boolean result = false; try { final String hashedWord = hashWord(testWord); final boolean inDB = localDB.contains(WORDS_DB, hashedWord); if (inDB) { final long timeStamp = Long.parseLong(localDB.get(WORDS_DB, hashedWord)); final long entryAge = System.currentTimeMillis() - timeStamp; if (entryAge < settings.maxAgeMs) { result = true; } } } catch (Exception e) { LOGGER.warn("error checking global history list: " + e.getMessage()); } // LOGGER.trace(pwmSession, "successfully checked word, result=" + result + ", duration=" + new // TimeDuration(System.currentTimeMillis(), startTime).asCompactString()); return result; }
public synchronized void addWord(final PwmSession pwmSession, final String word) { if (status != STATUS.OPEN) { return; } final String addWord = normalizeWord(word); if (addWord == null) { return; } final long startTime = System.currentTimeMillis(); try { final String hashedWord = hashWord(addWord); final boolean preExisting = localDB.contains(WORDS_DB, hashedWord); localDB.put(WORDS_DB, hashedWord, Long.toString(System.currentTimeMillis())); { final StringBuilder logOutput = new StringBuilder(); logOutput.append(preExisting ? "updated" : "added").append(" word"); logOutput .append(" (") .append(new TimeDuration(System.currentTimeMillis(), startTime).asCompactString()) .append(")"); logOutput.append(" (").append(this.size()).append(" total words)"); LOGGER.trace(logOutput.toString()); } } catch (Exception e) { LOGGER.warn(pwmSession, "error adding word to global history list: " + e.getMessage()); } }
public static LocalDB initializeLocalDB(final PwmApplication pwmApplication) { if (pwmApplication.getApplicationMode() == MODE.ERROR || pwmApplication.getApplicationMode() == MODE.NEW) { LOGGER.warn( "skipping LocalDB open due to application mode " + pwmApplication.getApplicationMode()); return null; } final File databaseDirectory; // see if META-INF isn't already there, then use WEB-INF. try { final String localDBLocationSetting = pwmApplication.getConfig().readSettingAsString(PwmSetting.PWMDB_LOCATION); databaseDirectory = Helper.figureFilepath(localDBLocationSetting, pwmApplication.applicationPath); } catch (Exception e) { pwmApplication.lastLocalDBFailure = new ErrorInformation( PwmError.ERROR_LOCALDB_UNAVAILABLE, "error locating configured LocalDB directory: " + e.getMessage()); LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr()); return null; } LOGGER.debug("using localDB path " + databaseDirectory); // initialize the localDB try { final boolean readOnly = pwmApplication.getApplicationMode() == MODE.READ_ONLY; return LocalDBFactory.getInstance( databaseDirectory, readOnly, pwmApplication, pwmApplication.getConfig()); } catch (Exception e) { pwmApplication.lastLocalDBFailure = new ErrorInformation( PwmError.ERROR_LOCALDB_UNAVAILABLE, "unable to initialize LocalDB: " + e.getMessage()); LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr()); } return null; }
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); } }
public void sendSmsUsingQueue(final SmsItemBean smsItem, final MacroMachine macroMachine) { final SmsQueueManager smsQueue = getSmsQueue(); if (smsQueue == null) { LOGGER.error("SMS queue is unavailable, unable to send SMS: " + smsItem.toString()); return; } final SmsItemBean rewrittenSmsItem = new SmsItemBean( macroMachine.expandMacros(smsItem.getTo()), macroMachine.expandMacros(smsItem.getMessage())); try { smsQueue.addSmsToQueue(rewrittenSmsItem); } catch (PwmUnrecoverableException e) { LOGGER.warn("unable to add sms to queue: " + e.getMessage()); } }
public static PwmPasswordPolicy readLdapPasswordPolicy( final PwmApplication pwmApplication, final ChaiUser theUser) throws PwmUnrecoverableException { try { final Map<String, String> ruleMap = new HashMap<>(); final ChaiPasswordPolicy chaiPolicy; try { chaiPolicy = theUser.getPasswordPolicy(); } catch (ChaiUnavailableException e) { throw new PwmUnrecoverableException(PwmError.forChaiError(e.getErrorCode())); } if (chaiPolicy != null) { for (final String key : chaiPolicy.getKeys()) { ruleMap.put(key, chaiPolicy.getValue(key)); } if (!"read" .equals( pwmApplication .getConfig() .readSettingAsString(PwmSetting.PASSWORD_POLICY_CASE_SENSITIVITY))) { ruleMap.put( PwmPasswordRule.CaseSensitive.getKey(), pwmApplication .getConfig() .readSettingAsString(PwmSetting.PASSWORD_POLICY_CASE_SENSITIVITY)); } return PwmPasswordPolicy.createPwmPasswordPolicy(ruleMap, chaiPolicy); } } catch (ChaiOperationException e) { LOGGER.warn( "error reading password policy for user " + theUser.getEntryDN() + ", error: " + e.getMessage()); } return PwmPasswordPolicy.defaultPolicy(); }
private void handleCreateRequest( final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean) throws PwmUnrecoverableException, ChaiUnavailableException, IOException, ServletException { final PwmSession pwmSession = pwmRequest.getPwmSession(); final PwmApplication pwmApplication = pwmRequest.getPwmApplication(); final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean(); final Configuration config = pwmApplication.getConfig(); final Locale locale = ssBean.getLocale(); final List<FormConfiguration> guestUserForm = config.readSettingAsForm(PwmSetting.GUEST_FORM); try { // read the values from the request final Map<FormConfiguration, String> formValues = FormUtility.readFormValuesFromRequest(pwmRequest, guestUserForm, locale); // read the expiration date from the request. final Date expirationDate = readExpirationFromRequest(pwmRequest); // see if the values meet form requirements. FormUtility.validateFormValues(config, formValues, locale); // read new user DN final String guestUserDN = determineUserDN(formValues, config); // read a chai provider to make the user final ChaiProvider provider = pwmSession.getSessionManager().getChaiProvider(); // set up the user creation attributes final Map<String, String> createAttributes = new HashMap<>(); for (final FormConfiguration formItem : formValues.keySet()) { LOGGER.debug( pwmSession, "Attribute from form: " + formItem.getName() + " = " + formValues.get(formItem)); final String n = formItem.getName(); final String v = formValues.get(formItem); if (n != null && n.length() > 0 && v != null && v.length() > 0) { createAttributes.put(n, v); } } // Write creator DN createAttributes.put( config.readSettingAsString(PwmSetting.GUEST_ADMIN_ATTRIBUTE), pwmSession.getUserInfoBean().getUserIdentity().getUserDN()); // read the creation object classes. final Set<String> createObjectClasses = new HashSet<>(config.readSettingAsStringArray(PwmSetting.DEFAULT_OBJECT_CLASSES)); provider.createEntry(guestUserDN, createObjectClasses, createAttributes); LOGGER.info(pwmSession, "created user object: " + guestUserDN); final ChaiUser theUser = ChaiFactory.createChaiUser(guestUserDN, provider); final UserIdentity userIdentity = new UserIdentity( guestUserDN, pwmSession.getUserInfoBean().getUserIdentity().getLdapProfileID()); // write the expiration date: if (expirationDate != null) { final String expirationAttr = config.readSettingAsString(PwmSetting.GUEST_EXPIRATION_ATTRIBUTE); theUser.writeDateAttribute(expirationAttr, expirationDate); } final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser( pwmApplication, pwmSession.getLabel(), userIdentity, theUser, locale); final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword( pwmSession.getLabel(), passwordPolicy, pwmApplication); theUser.setPassword(newPassword.getStringValue()); /* final UserInfoBean guestUserInfoBean = new UserInfoBean(); final UserStatusReader userStatusReader = new UserStatusReader(pwmApplication); userStatusReader.populateUserInfoBean( pwmSession.getLabel(), guestUserInfoBean, pwmSession.getSessionStateBean().getLocale(), userIdentity, theUser.getChaiProvider() ); */ { // execute configured actions LOGGER.debug(pwmSession, "executing configured actions to user " + theUser.getEntryDN()); final List<ActionConfiguration> actions = pwmApplication.getConfig().readSettingAsAction(PwmSetting.GUEST_WRITE_ATTRIBUTES); if (actions != null && !actions.isEmpty()) { final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, userIdentity); final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, theUser) .setExpandPwmMacros(true) .setMacroMachine(macroMachine) .createActionExecutor(); actionExecutor.executeActions(actions, pwmSession); } } // everything good so forward to success page. this.sendGuestUserEmailConfirmation(pwmRequest, userIdentity); pwmApplication.getStatisticsManager().incrementValue(Statistic.NEW_USERS); pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_CreateGuest); } catch (ChaiOperationException e) { final ErrorInformation info = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE, "error creating user: " + e.getMessage()); pwmRequest.setResponseError(info); LOGGER.warn(pwmSession, info); this.forwardToJSP(pwmRequest, guestRegistrationBean); } catch (PwmOperationalException e) { LOGGER.error(pwmSession, e.getErrorInformation().toDebugStr()); pwmRequest.setResponseError(e.getErrorInformation()); this.forwardToJSP(pwmRequest, guestRegistrationBean); } }
protected void handleSearchRequest( final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean) throws ServletException, ChaiUnavailableException, IOException, PwmUnrecoverableException { LOGGER.trace(pwmRequest, "Enter: handleSearchRequest(...)"); final PwmSession pwmSession = pwmRequest.getPwmSession(); final PwmApplication pwmApplication = pwmRequest.getPwmApplication(); final ChaiProvider chaiProvider = pwmSession.getSessionManager().getChaiProvider(); final Configuration config = pwmApplication.getConfig(); final String adminDnAttribute = config.readSettingAsString(PwmSetting.GUEST_ADMIN_ATTRIBUTE); final Boolean origAdminOnly = config.readSettingAsBoolean(PwmSetting.GUEST_EDIT_ORIG_ADMIN_ONLY); final String usernameParam = pwmRequest.readParameterAsString("username"); final GuestRegistrationBean guBean = pwmApplication.getSessionStateService().getBean(pwmRequest, GuestRegistrationBean.class); final UserSearchEngine.SearchConfiguration searchConfiguration = new UserSearchEngine.SearchConfiguration(); searchConfiguration.setChaiProvider(chaiProvider); searchConfiguration.setContexts( Collections.singletonList(config.readSettingAsString(PwmSetting.GUEST_CONTEXT))); searchConfiguration.setEnableContextValidation(false); searchConfiguration.setUsername(usernameParam); final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmApplication, pwmSession.getLabel()); try { final UserIdentity theGuest = userSearchEngine.performSingleUserSearch(searchConfiguration); final FormMap formProps = guBean.getFormValues(); try { final List<FormConfiguration> guestUpdateForm = config.readSettingAsForm(PwmSetting.GUEST_UPDATE_FORM); final Set<String> involvedAttrs = new HashSet<>(); for (final FormConfiguration formItem : guestUpdateForm) { if (!formItem.getName().equalsIgnoreCase(HTTP_PARAM_EXPIRATION_DATE)) { involvedAttrs.add(formItem.getName()); } } final UserDataReader userDataReader = LdapUserDataReader.selfProxiedReader(pwmApplication, pwmSession, theGuest); final Map<String, String> userAttrValues = userDataReader.readStringAttributes(involvedAttrs); if (origAdminOnly && adminDnAttribute != null && adminDnAttribute.length() > 0) { final String origAdminDn = userAttrValues.get(adminDnAttribute); if (origAdminDn != null && origAdminDn.length() > 0) { if (!pwmSession .getUserInfoBean() .getUserIdentity() .getUserDN() .equalsIgnoreCase(origAdminDn)) { final ErrorInformation info = new ErrorInformation(PwmError.ERROR_ORIG_ADMIN_ONLY); pwmRequest.setResponseError(info); LOGGER.warn(pwmSession, info); this.forwardToJSP(pwmRequest, guestRegistrationBean); } } } final String expirationAttribute = config.readSettingAsString(PwmSetting.GUEST_EXPIRATION_ATTRIBUTE); if (expirationAttribute != null && expirationAttribute.length() > 0) { final Date expiration = userDataReader.readDateAttribute(expirationAttribute); if (expiration != null) { guBean.setUpdateUserExpirationDate(expiration); } } for (final FormConfiguration formItem : guestUpdateForm) { final String key = formItem.getName(); final String value = userAttrValues.get(key); if (value != null) { formProps.put(key, value); } } guBean.setUpdateUserIdentity(theGuest); this.forwardToUpdateJSP(pwmRequest, guestRegistrationBean); return; } catch (ChaiOperationException e) { LOGGER.warn(pwmSession, "error reading current attributes for user: " + e.getMessage()); } } catch (PwmOperationalException e) { final ErrorInformation error = e.getErrorInformation(); pwmRequest.setResponseError(error); this.forwardToJSP(pwmRequest, guestRegistrationBean); return; } this.forwardToJSP(pwmRequest, guestRegistrationBean); }
private void verifyIfApplicationPathIsSetProperly(final PwmEnvironment pwmEnvironment) throws PwmUnrecoverableException { final File applicationPath = pwmEnvironment.applicationPath; File webInfPath = pwmEnvironment.webInfPath; verifyApplicationPath(applicationPath); boolean applicationPathIsWebInfPath = false; if (applicationPath.equals(webInfPath)) { applicationPathIsWebInfPath = true; } else if (applicationPath.getAbsolutePath().endsWith("/WEB-INF")) { final File webXmlFile = new File(applicationPath.getAbsolutePath() + File.separator + "web.xml"); if (webXmlFile.exists()) { applicationPathIsWebInfPath = true; } } if (applicationPathIsWebInfPath) { if (webInfPath == null) { webInfPath = applicationPath; pwmEnvironment.webInfPath = applicationPath; } LOGGER.trace("applicationPath appears to be servlet /WEB-INF directory"); } if (webInfPath != null) { final File infoFile = new File( webInfPath.getAbsolutePath() + File.separator + PwmConstants.APPLICATION_PATH_INFO_FILE); if (applicationPathIsWebInfPath) { if (pwmEnvironment.applicationPathType == PwmEnvironment.ApplicationPathType.derived) { LOGGER.trace( "checking " + infoFile.getAbsolutePath() + " status, (applicationPathType=" + PwmEnvironment.ApplicationPathType.derived + ")"); if (infoFile.exists()) { final String errorMsg = "The file " + infoFile.getAbsolutePath() + " exists, and an applicationPath was not explicitly specified." + " This happens when an applicationPath was previously configured, but is not now being specified." + " An explicit applicationPath parameter must be specified, or the file can be removed if the applicationPath should be changed to the default /WEB-INF directory."; throw new PwmUnrecoverableException( new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg)); } else { LOGGER.trace("marker file " + infoFile.getAbsolutePath() + " does not exist"); } } } else { if (pwmEnvironment.applicationPathType == PwmEnvironment.ApplicationPathType.specified) { try { final FileOutputStream fos = new FileOutputStream(infoFile); final Properties outputProperties = new Properties(); outputProperties.setProperty("lastApplicationPath", applicationPath.getAbsolutePath()); outputProperties.store( fos, "Marker file to record a previously configured applicationPath"); } catch (IOException e) { LOGGER.warn( "unable to write applicationPath marker properties file " + infoFile.getAbsolutePath() + ""); } } } } }
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()); }
public void init(final PwmApplication pwmApplication) throws PwmException { settings.maxAgeMs = 1000 * pwmApplication .getConfig() .readSettingAsLong(PwmSetting.PASSWORD_SHAREDHISTORY_MAX_AGE); // convert to MS; settings.caseInsensitive = Boolean.parseBoolean( pwmApplication .getConfig() .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_CASE_INSENSITIVE)); settings.hashName = pwmApplication.getConfig().readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_HASH_NAME); settings.hashIterations = Integer.parseInt( pwmApplication .getConfig() .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_HASH_ITERATIONS)); settings.version = "2" + "_" + settings.hashName + "_" + settings.hashIterations + "_" + settings.caseInsensitive; final int SALT_LENGTH = Integer.parseInt( pwmApplication .getConfig() .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_SALT_LENGTH)); this.localDB = pwmApplication.getLocalDB(); boolean needsClearing = false; if (localDB == null) { LOGGER.info("LocalDB is not available, will remain closed"); status = STATUS.CLOSED; return; } if (settings.maxAgeMs < 1) { LOGGER.debug("max age=" + settings.maxAgeMs + ", will remain closed"); needsClearing = true; } { this.salt = localDB.get(META_DB, KEY_SALT); if (salt == null || salt.length() < SALT_LENGTH) { LOGGER.warn("stored global salt value is not present, creating new salt"); this.salt = PwmRandom.getInstance().alphaNumericString(SALT_LENGTH); localDB.put(META_DB, KEY_SALT, this.salt); needsClearing = true; } } if (needsClearing) { LOGGER.trace("clearing wordlist"); try { localDB.truncate(WORDS_DB); } catch (Exception e) { LOGGER.error("error during wordlist truncate", e); } } new Thread( new Runnable() { public void run() { LOGGER.debug("starting up in background thread"); init(pwmApplication, settings.maxAgeMs); } }, Helper.makeThreadName(pwmApplication, this.getClass()) + " initializer") .start(); }
public static void helpdeskSetUserPassword( final PwmSession pwmSession, final ChaiUser chaiUser, final UserIdentity userIdentity, final PwmApplication pwmApplication, final PasswordData newPassword) throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException { final SessionLabel sessionLabel = pwmSession.getLabel(); if (!pwmSession.isAuthenticated()) { final String errorMsg = "attempt to helpdeskSetUserPassword, but user is not authenticated"; final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg); throw new PwmOperationalException(errorInformation); } final HelpdeskProfile helpdeskProfile = pwmSession.getSessionManager().getHelpdeskProfile(pwmApplication); if (helpdeskProfile == null) { final String errorMsg = "attempt to helpdeskSetUserPassword, but user does not have helpdesk permission"; final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg); throw new PwmOperationalException(errorInformation); } try { chaiUser.setPassword(newPassword.getStringValue()); } catch (ChaiPasswordPolicyException e) { final String errorMsg = "error setting password for user '" + chaiUser.getEntryDN() + "'' " + e.toString(); final PwmError pwmError = PwmError.forChaiError(e.getErrorCode()); final ErrorInformation error = new ErrorInformation( pwmError == null ? PwmError.PASSWORD_UNKNOWN_VALIDATION : pwmError, errorMsg); throw new PwmOperationalException(error); } catch (ChaiOperationException e) { final String errorMsg = "error setting password for user '" + chaiUser.getEntryDN() + "'' " + e.getMessage(); final PwmError pwmError = PwmError.forChaiError(e.getErrorCode()) == null ? PwmError.ERROR_UNKNOWN : PwmError.forChaiError(e.getErrorCode()); final ErrorInformation error = new ErrorInformation(pwmError, errorMsg); throw new PwmOperationalException(error); } // at this point the password has been changed, so log it. LOGGER.info( sessionLabel, "user '" + pwmSession.getUserInfoBean().getUserIdentity() + "' successfully changed password for " + chaiUser.getEntryDN()); // create a proxy user object for pwm to update/read the user. final ChaiUser proxiedUser = pwmApplication.getProxiedChaiUser(userIdentity); // mark the event log { final HelpdeskAuditRecord auditRecord = pwmApplication .getAuditManager() .createHelpdeskAuditRecord( AuditEvent.HELPDESK_SET_PASSWORD, pwmSession.getUserInfoBean().getUserIdentity(), null, userIdentity, pwmSession.getSessionStateBean().getSrcAddress(), pwmSession.getSessionStateBean().getSrcHostname()); pwmApplication.getAuditManager().submit(auditRecord); } // update statistics pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES, 1); pwmApplication.getStatisticsManager().incrementValue(Statistic.HELPDESK_PASSWORD_SET); // create a uib for end user final UserInfoBean userInfoBean = new UserInfoBean(); final UserStatusReader userStatusReader = new UserStatusReader(pwmApplication, pwmSession.getLabel()); userStatusReader.populateUserInfoBean( userInfoBean, pwmSession.getSessionStateBean().getLocale(), userIdentity, proxiedUser.getChaiProvider()); { // execute configured actions LOGGER.debug( sessionLabel, "executing changepassword and helpdesk post password change writeAttributes to user " + userIdentity); final List<ActionConfiguration> actions = new ArrayList<>(); actions.addAll( pwmApplication .getConfig() .readSettingAsAction(PwmSetting.CHANGE_PASSWORD_WRITE_ATTRIBUTES)); actions.addAll( helpdeskProfile.readSettingAsAction( PwmSetting.HELPDESK_POST_SET_PASSWORD_WRITE_ATTRIBUTES)); if (!actions.isEmpty()) { final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity) .setMacroMachine( MacroMachine.forUser( pwmApplication, pwmSession.getSessionStateBean().getLocale(), sessionLabel, userIdentity)) .setExpandPwmMacros(true) .createActionExecutor(); actionExecutor.executeActions(actions, pwmSession); } } final HelpdeskClearResponseMode settingClearResponses = HelpdeskClearResponseMode.valueOf( helpdeskProfile.readSettingAsString(PwmSetting.HELPDESK_CLEAR_RESPONSES)); if (settingClearResponses == HelpdeskClearResponseMode.yes) { final String userGUID = LdapOperationsHelper.readLdapGuidValue(pwmApplication, sessionLabel, userIdentity, false); pwmApplication.getCrService().clearResponses(pwmSession, proxiedUser, userGUID); // mark the event log final HelpdeskAuditRecord auditRecord = pwmApplication .getAuditManager() .createHelpdeskAuditRecord( AuditEvent.HELPDESK_CLEAR_RESPONSES, pwmSession.getUserInfoBean().getUserIdentity(), null, userIdentity, pwmSession.getSessionStateBean().getSrcAddress(), pwmSession.getSessionStateBean().getSrcHostname()); pwmApplication.getAuditManager().submit(auditRecord); } // send email notification sendChangePasswordHelpdeskEmailNotice(pwmSession, pwmApplication, userInfoBean); // expire if so configured if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_FORCE_PW_EXPIRATION)) { LOGGER.trace( pwmSession, "preparing to expire password for user " + userIdentity.toDisplayString()); try { proxiedUser.expirePassword(); } catch (ChaiOperationException e) { LOGGER.warn( pwmSession, "error while forcing password expiration for user " + userIdentity.toDisplayString() + ", error: " + e.getMessage()); e.printStackTrace(); } } // send password final boolean sendPassword = helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_SEND_PASSWORD); if (sendPassword) { final MessageSendMethod messageSendMethod; { final String profileID = ProfileUtility.discoverProfileIDforUser( pwmApplication, sessionLabel, userIdentity, ProfileType.ForgottenPassword); final ForgottenPasswordProfile forgottenPasswordProfile = pwmApplication.getConfig().getForgottenPasswordProfiles().get(profileID); messageSendMethod = forgottenPasswordProfile.readSettingAsEnum( PwmSetting.RECOVERY_SENDNEWPW_METHOD, MessageSendMethod.class); } final UserDataReader userDataReader = new LdapUserDataReader(userIdentity, chaiUser); final LoginInfoBean loginInfoBean = new LoginInfoBean(); loginInfoBean.setUserCurrentPassword(newPassword); final MacroMachine macroMachine = new MacroMachine( pwmApplication, pwmSession.getLabel(), userInfoBean, loginInfoBean, userDataReader); PasswordUtility.sendNewPassword( userInfoBean, pwmApplication, macroMachine, newPassword, pwmSession.getSessionStateBean().getLocale(), messageSendMethod); } }
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; }