public void clearResponses(final ChaiUser theUser, final String userGUID) throws PwmUnrecoverableException { if (userGUID == null || userGUID.length() < 1) { throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_MISSING_GUID, "cannot clear responses to remote database, user " + theUser.getEntryDN() + " does not have a guid")); } try { final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor(); databaseAccessor.remove(DatabaseTable.PWM_RESPONSES, userGUID); LOGGER.info("cleared responses for user " + theUser.getEntryDN() + " in remote database"); } catch (DatabaseException e) { final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_CLEARING_RESPONSES, "unexpected error clearing responses for " + theUser.getEntryDN() + " in remote database, error: " + e.getMessage()); final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo); pwmOE.initCause(e); throw pwmOE; } }
private String oraclePreTemporaryPwHandler( final ChaiProvider chaiProvider, final ChaiUser chaiUser) throws PwmUnrecoverableException, ChaiUnavailableException, ChaiOperationException { if (!pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.ORACLE_DS_ENABLE_MANIP_ALLOWCHANGETIME)) { return null; } if (ChaiProvider.DIRECTORY_VENDOR.ORACLE_DS != chaiUser.getChaiProvider().getDirectoryVendor()) { return null; } // oracle DS special case: passwordAllowChangeTime handler final String oracleDS_PrePasswordAllowChangeTime = chaiProvider.readStringAttribute(chaiUser.getEntryDN(), ORACLE_ATTR_PW_ALLOW_CHG_TIME); log( PwmLogLevel.TRACE, "read OracleDS value of passwordAllowChangeTime value=" + oracleDS_PrePasswordAllowChangeTime); if (oracleDS_PrePasswordAllowChangeTime != null && !oracleDS_PrePasswordAllowChangeTime.isEmpty()) { final Date date = OracleDSEntries.convertZuluToDate(oracleDS_PrePasswordAllowChangeTime); if (new Date().before(date)) { final String errorMsg = "change not permitted until " + PwmConstants.DEFAULT_DATETIME_FORMAT.format(date); throw new PwmUnrecoverableException( new ErrorInformation(PwmError.PASSWORD_TOO_SOON, errorMsg)); } } return oracleDS_PrePasswordAllowChangeTime; }
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()); }
private PasswordData setTempUserPassword() throws ChaiUnavailableException, ImpossiblePasswordPolicyException, PwmUnrecoverableException { final boolean configAlwaysUseProxy = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.AD_USE_PROXY_FOR_FORGOTTEN); final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final ChaiUser chaiUser = ChaiFactory.createChaiUser(userIdentity.getUserDN(), chaiProvider); // try setting a random password on the account to authenticate. if (!configAlwaysUseProxy && requestedAuthType == AuthenticationType.AUTH_FROM_PUBLIC_MODULE) { log(PwmLogLevel.DEBUG, "attempting to set temporary random password"); PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser( pwmApplication, sessionLabel, userIdentity, chaiUser, PwmConstants.DEFAULT_LOCALE); // create random password for user RandomPasswordGenerator.RandomGeneratorConfig randomGeneratorConfig = new RandomPasswordGenerator.RandomGeneratorConfig(); randomGeneratorConfig.setSeedlistPhrases(RandomPasswordGenerator.DEFAULT_SEED_PHRASES); randomGeneratorConfig.setPasswordPolicy(passwordPolicy); final PasswordData currentPass = RandomPasswordGenerator.createRandomPassword( sessionLabel, randomGeneratorConfig, pwmApplication); try { final String oracleDS_PrePasswordAllowChangeTime = oraclePreTemporaryPwHandler(chaiProvider, chaiUser); // write the random password for the user. chaiUser.setPassword(currentPass.getStringValue()); oraclePostTemporaryPwHandler(chaiProvider, chaiUser, oracleDS_PrePasswordAllowChangeTime); log( PwmLogLevel.INFO, "user " + userIdentity + " password has been set to random value to use for user authentication"); } catch (ChaiOperationException e) { final String errorStr = "error setting random password for user " + userIdentity + " " + e.getMessage(); log(PwmLogLevel.ERROR, errorStr); throw new PwmUnrecoverableException( new ErrorInformation(PwmError.ERROR_BAD_SESSION_PASSWORD, errorStr)); } return currentPass; } return null; }
public ResponseSet readResponseSet( final ChaiUser theUser, final UserIdentity userIdentity, final String userGUID) throws PwmUnrecoverableException { if (userGUID == null || userGUID.length() < 1) { final String errorMsg = "user " + theUser.getEntryDN() + " does not have a guid, unable to search for responses in remote database"; final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_MISSING_GUID, errorMsg); throw new PwmUnrecoverableException(errorInformation); } try { final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor(); final String responseStringBlob = databaseAccessor.get(DatabaseTable.PWM_RESPONSES, userGUID); if (responseStringBlob != null && responseStringBlob.length() > 0) { final ResponseSet userResponseSet = ChaiResponseSet.parseChaiResponseSetXML(responseStringBlob, theUser); LOGGER.debug( "found responses for " + theUser.getEntryDN() + " in remote database: " + userResponseSet.toString()); return userResponseSet; } else { LOGGER.trace( "user guid for " + theUser.getEntryDN() + " not found in remote database (key=" + userGUID + ")"); } } catch (ChaiValidationException e) { final String errorMsg = "unexpected error reading responses for " + theUser.getEntryDN() + " from remote database: " + e.getMessage(); final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg); throw new PwmUnrecoverableException(errorInformation); } catch (PwmOperationalException e) { final String errorMsg = "unexpected error reading responses for " + theUser.getEntryDN() + " from remote database: " + e.getMessage(); final ErrorInformation errorInformation = new ErrorInformation(e.getErrorInformation().getError(), errorMsg); throw new PwmUnrecoverableException(errorInformation); } return null; }
private static Date determinePwdLastModified( final PwmApplication pwmApplication, final SessionLabel sessionLabel, final ChaiUser theUser, final UserIdentity userIdentity) throws ChaiUnavailableException, PwmUnrecoverableException { // fetch last password modification time from pwm last update attribute operation try { final Date chaiReadDate = theUser.readPasswordModificationDate(); if (chaiReadDate != null) { LOGGER.trace( sessionLabel, "read last user password change timestamp (via chai) as: " + PwmConstants.DEFAULT_DATETIME_FORMAT.format(chaiReadDate)); return chaiReadDate; } } catch (ChaiOperationException e) { LOGGER.error( sessionLabel, "unexpected error reading password last modified timestamp: " + e.getMessage()); } final LdapProfile ldapProfile = pwmApplication.getConfig().getLdapProfiles().get(userIdentity.getLdapProfileID()); final String pwmLastSetAttr = ldapProfile.readSettingAsString(PwmSetting.PASSWORD_LAST_UPDATE_ATTRIBUTE); if (pwmLastSetAttr != null && pwmLastSetAttr.length() > 0) { try { final Date pwmPwdLastModified = theUser.readDateAttribute(pwmLastSetAttr); LOGGER.trace( sessionLabel, "read pwmPasswordChangeTime as: " + (pwmPwdLastModified == null ? "n/a" : PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmPwdLastModified))); return pwmPwdLastModified; } catch (ChaiOperationException e) { LOGGER.error( sessionLabel, "error parsing password last modified PWM password value for user " + theUser.getEntryDN() + "; error: " + e.getMessage()); } } LOGGER.debug(sessionLabel, "unable to determine time of user's last password modification"); return null; }
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 PasswordData learnUserPassword() throws ChaiUnavailableException, PwmUnrecoverableException { log(PwmLogLevel.TRACE, "beginning auth processes for user with unknown password"); if (userIdentity == null || userIdentity.getUserDN() == null || userIdentity.getUserDN().length() < 1) { throw new NullPointerException("invalid user (null)"); } final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final ChaiUser chaiUser = ChaiFactory.createChaiUser(userIdentity.getUserDN(), chaiProvider); // use chai (nmas) to retrieve user password if (pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.EDIRECTORY_READ_USER_PWD)) { String currentPass = null; try { final String readPassword = chaiUser.readPassword(); if (readPassword != null && readPassword.length() > 0) { currentPass = readPassword; log( PwmLogLevel.DEBUG, "successfully retrieved user's current password from ldap, now conducting standard authentication"); } } catch (Exception e) { log(PwmLogLevel.ERROR, "unable to retrieve user password from ldap: " + e.getMessage()); } // actually do the authentication since we have user pw. if (currentPass != null && currentPass.length() > 0) { return new PasswordData(currentPass); } } else { log(PwmLogLevel.TRACE, "skipping attempt to read user password, option disabled"); } return null; }
private void oraclePostTemporaryPwHandler( final ChaiProvider chaiProvider, final ChaiUser chaiUser, final String oracleDS_PrePasswordAllowChangeTime) throws ChaiUnavailableException, ChaiOperationException { if (!pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.ORACLE_DS_ENABLE_MANIP_ALLOWCHANGETIME)) { return; } // oracle DS special case: passwordAllowChangeTime handler if (ChaiProvider.DIRECTORY_VENDOR.ORACLE_DS != chaiUser.getChaiProvider().getDirectoryVendor()) { return; } if (oracleDS_PrePasswordAllowChangeTime != null && !oracleDS_PrePasswordAllowChangeTime.isEmpty()) { // write back the original pre-password allow change time. final Set<String> values = new HashSet<>(Collections.singletonList(oracleDS_PrePasswordAllowChangeTime)); chaiProvider.writeStringAttribute( chaiUser.getEntryDN(), ORACLE_ATTR_PW_ALLOW_CHG_TIME, values, true); log( PwmLogLevel.TRACE, "re-wrote passwordAllowChangeTime attribute to user " + chaiUser.getEntryDN() + ", value=" + oracleDS_PrePasswordAllowChangeTime); } else { final String oracleDS_PostPasswordAllowChangeTime = chaiProvider.readStringAttribute(chaiUser.getEntryDN(), ORACLE_ATTR_PW_ALLOW_CHG_TIME); if (oracleDS_PostPasswordAllowChangeTime != null && !oracleDS_PostPasswordAllowChangeTime.isEmpty()) { // password allow change time has appeared, but wasn't present previously, so delete it. log( PwmLogLevel.TRACE, "a new value for passwordAllowChangeTime attribute to user " + chaiUser.getEntryDN() + " has appeared, will remove"); chaiProvider.deleteStringAttributeValue( chaiUser.getEntryDN(), ORACLE_ATTR_PW_ALLOW_CHG_TIME, oracleDS_PostPasswordAllowChangeTime); log( PwmLogLevel.TRACE, "deleted attribute value for passwordAllowChangeTime attribute on user " + chaiUser.getEntryDN()); } } }
public ResponseInfoBean readResponseInfo( ChaiUser theUser, final UserIdentity userIdentity, String userGUID) throws PwmUnrecoverableException { try { final ResponseSet responseSet = readResponseSet(theUser, userIdentity, userGUID); return responseSet == null ? null : CrOperators.convertToNoAnswerInfoBean(responseSet, DataStorageMethod.DB); } catch (ChaiException e) { throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_RESPONSES_NORESPONSES, "unexpected error reading response info for " + theUser.getEntryDN() + ", error: " + e.getMessage())); } }
private static ResponseSet readResponsesFromNovellUA( final PwmApplication pwmApplication, final ChaiUser theUser) throws PwmUnrecoverableException { final String novellUserAppWebServiceURL = pwmApplication .getConfig() .readSettingAsString(PwmSetting.EDIRECTORY_PWD_MGT_WEBSERVICE_URL); try { LOGGER.trace("establishing connection to web service at " + novellUserAppWebServiceURL); final PasswordManagementServiceLocator locater = new PasswordManagementServiceLocator(); final PasswordManagement service = locater.getPasswordManagementPort(new URL(novellUserAppWebServiceURL)); ((Stub) service)._setProperty(javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); final ProcessUserRequest userRequest = new ProcessUserRequest(theUser.getEntryDN()); final ForgotPasswordWSBean processUserResponse = service.processUser(userRequest); if (processUserResponse.isTimeout() || processUserResponse.isError()) { throw new Exception( "novell web service reports " + (processUserResponse.isTimeout() ? "timeout" : "error") + ": " + processUserResponse.getMessage()); } if (processUserResponse.getChallengeQuestions() != null) { return new NovellWSResponseSet(service, processUserResponse); } } catch (Throwable e) { final String errorMsg = "error retrieving novell user responses from web service: " + e.getMessage(); final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_UNREACHABLE, errorMsg); throw new PwmUnrecoverableException(errorInformation); } return null; }
@Override public void writeResponses(ChaiUser theUser, String userGUID, ResponseInfoBean responseInfoBean) throws PwmUnrecoverableException { if (userGUID == null || userGUID.length() < 1) { throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_MISSING_GUID, "cannot save responses to remote database, user " + theUser.getEntryDN() + " does not have a guid")); } LOGGER.trace( "attempting to save responses for " + theUser.getEntryDN() + " in remote database (key=" + userGUID + ")"); try { final ChaiResponseSet responseSet = ChaiCrFactory.newChaiResponseSet( responseInfoBean.getCrMap(), responseInfoBean.getHelpdeskCrMap(), responseInfoBean.getLocale(), responseInfoBean.getMinRandoms(), theUser.getChaiProvider().getChaiConfiguration(), responseInfoBean.getCsIdentifier()); final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor(); databaseAccessor.put(DatabaseTable.PWM_RESPONSES, userGUID, responseSet.stringValue()); LOGGER.info( "saved responses for " + theUser.getEntryDN() + " in remote database (key=" + userGUID + ")"); } catch (ChaiException e) { final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_WRITING_RESPONSES, "unexpected error saving responses for " + theUser.getEntryDN() + " in remote database: " + e.getMessage()); final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo); LOGGER.error(errorInfo.toDebugStr()); pwmOE.initCause(e); throw pwmOE; } catch (DatabaseException e) { final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_WRITING_RESPONSES, "unexpected error saving responses for " + theUser.getEntryDN() + " in remote database: " + e.getMessage()); final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo); LOGGER.error(errorInfo.toDebugStr()); pwmOE.initCause(e); throw pwmOE; } }
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 handleUpdateRequest( final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean) throws ServletException, ChaiUnavailableException, IOException, PwmUnrecoverableException { // Fetch the session state bean. final PwmSession pwmSession = pwmRequest.getPwmSession(); final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean(); final PwmApplication pwmApplication = pwmRequest.getPwmApplication(); final Configuration config = pwmApplication.getConfig(); final List<FormConfiguration> formItems = pwmApplication.getConfig().readSettingAsForm(PwmSetting.GUEST_UPDATE_FORM); final String expirationAttribute = config.readSettingAsString(PwmSetting.GUEST_EXPIRATION_ATTRIBUTE); try { // read the values from the request final Map<FormConfiguration, String> formValues = FormUtility.readFormValuesFromRequest(pwmRequest, formItems, pwmRequest.getLocale()); // see if the values meet form requirements. FormUtility.validateFormValues(config, formValues, ssBean.getLocale()); // read current values from user. final ChaiUser theGuest = pwmSession .getSessionManager() .getActor(pwmApplication, guestRegistrationBean.getUpdateUserIdentity()); // check unique fields against ldap FormUtility.validateFormValueUniqueness( pwmApplication, formValues, ssBean.getLocale(), Collections.singletonList(guestRegistrationBean.getUpdateUserIdentity()), false); final Date expirationDate = readExpirationFromRequest(pwmRequest); // Update user attributes Helper.writeFormValuesToLdap(pwmApplication, pwmSession, theGuest, formValues, false); // Write expirationDate if (expirationDate != null) { theGuest.writeDateAttribute(expirationAttribute, expirationDate); } // send email. final UserStatusReader userStatusReader = new UserStatusReader(pwmApplication, pwmSession.getLabel()); final UserInfoBean guestUserInfoBean = new UserInfoBean(); userStatusReader.populateUserInfoBean( guestUserInfoBean, pwmSession.getSessionStateBean().getLocale(), guestRegistrationBean.getUpdateUserIdentity(), theGuest.getChaiProvider()); this.sendUpdateGuestEmailConfirmation(pwmRequest, guestUserInfoBean); pwmApplication.getStatisticsManager().incrementValue(Statistic.UPDATED_GUESTS); // everything good so forward to confirmation page. pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_UpdateGuest); return; } catch (PwmOperationalException e) { LOGGER.error(pwmSession, e.getErrorInformation().toDebugStr()); pwmRequest.setResponseError(e.getErrorInformation()); } catch (ChaiOperationException e) { final ErrorInformation info = new ErrorInformation( PwmError.ERROR_UNKNOWN, "unexpected error writing to ldap: " + e.getMessage()); LOGGER.error(pwmSession, info); pwmRequest.setResponseError(info); } this.forwardToUpdateJSP(pwmRequest, guestRegistrationBean); }
@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()); }
/** * This is the entry point under which all password changes are managed. The following is the * general procedure when this method is invoked. * * <ul> * <li>password is checked against PWM password requirement * <li>ldap password set is attempted<br> * <br> * if successful: * <ul> * <li>uiBean is updated with old and new passwords * <li>uiBean's password expire flag is set to false * <li>any configured external methods are invoked * <li>user email notification is sent * <li>return true * </ul> * <br> * if unsuccessful * <ul> * <li>ssBean is updated with appropriate error * <li>return false * </ul> * </ul> * * @param newPassword the new password that is being set. * @param pwmSession beanmanager for config and user info lookup * @throws com.novell.ldapchai.exception.ChaiUnavailableException if the ldap directory is not * unavailable * @throws password.pwm.error.PwmUnrecoverableException if user is not authenticated */ public static void setActorPassword( final PwmSession pwmSession, final PwmApplication pwmApplication, final PasswordData newPassword) throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException { final UserInfoBean uiBean = pwmSession.getUserInfoBean(); if (!pwmSession .getSessionManager() .checkPermission(pwmApplication, Permission.CHANGE_PASSWORD)) { final String errorMsg = "attempt to setActorPassword, but user does not have password change permission"; final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg); throw new PwmOperationalException(errorInformation); } // double check to make sure password meets PWM rule requirements. This should // have been done before setActorPassword() is invoked, so it should be redundant // but we do it just in case. try { final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, uiBean.getPasswordPolicy()); pwmPasswordRuleValidator.testPassword( newPassword, null, uiBean, pwmSession.getSessionManager().getActor(pwmApplication)); } catch (PwmDataValidationException e) { final String errorMsg = "attempt to setActorPassword, but password does not pass local policy validator"; final ErrorInformation errorInformation = new ErrorInformation(e.getErrorInformation().getError(), errorMsg); throw new PwmOperationalException(errorInformation); } // retrieve the user's old password from the userInfoBean in the session final PasswordData oldPassword = pwmSession.getLoginInfoBean().getUserCurrentPassword(); boolean setPasswordWithoutOld = false; if (oldPassword == null) { if (pwmSession .getSessionManager() .getActor(pwmApplication) .getChaiProvider() .getDirectoryVendor() == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) { setPasswordWithoutOld = true; } } if (!setPasswordWithoutOld) { // Check to make sure we actually have an old password if (oldPassword == null) { final String errorMsg = "cannot set password for user, old password is not available"; final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg); throw new PwmOperationalException(errorInformation); } } try { final ChaiProvider provider = pwmSession.getSessionManager().getChaiProvider(); final ChaiUser theUser = ChaiFactory.createChaiUser( pwmSession.getUserInfoBean().getUserIdentity().getUserDN(), provider); final boolean boundAsSelf = theUser .getEntryDN() .equals(provider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN)); LOGGER.trace( pwmSession, "preparing to setActorPassword for '" + theUser.getEntryDN() + "', bindAsSelf=" + boundAsSelf + ", authType=" + pwmSession.getLoginInfoBean().getType()); if (setPasswordWithoutOld) { theUser.setPassword(newPassword.getStringValue(), true); } else { theUser.changePassword(oldPassword.getStringValue(), newPassword.getStringValue()); } } catch (ChaiPasswordPolicyException e) { final String errorMsg = "error setting password for user '" + uiBean.getUserIdentity() + "'' " + 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 '" + uiBean.getUserIdentity() + "'' " + 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( pwmSession, "user '" + uiBean.getUserIdentity() + "' successfully changed password"); // update the session state bean's password modified flag pwmSession.getSessionStateBean().setPasswordModified(true); // update the login info bean with the user's new password pwmSession.getLoginInfoBean().setUserCurrentPassword(newPassword); // close any outstanding ldap connections (since they cache the old password) pwmSession .getSessionManager() .updateUserPassword(pwmApplication, uiBean.getUserIdentity(), newPassword); // clear the "requires new password flag" uiBean.setRequiresNewPassword(false); // mark the auth type as authenticatePd now that we have the user's natural password. pwmSession.getLoginInfoBean().setType(AuthenticationType.AUTHENTICATED); // update the uibean's "password expired flag". final UserStatusReader userStatusReader = new UserStatusReader(pwmApplication, pwmSession.getLabel()); uiBean.setPasswordState( userStatusReader.readPasswordStatus( pwmSession.getSessionManager().getActor(pwmApplication), uiBean.getPasswordPolicy(), uiBean, newPassword)); // create a proxy user object for pwm to update/read the user. final ChaiUser proxiedUser = pwmSession.getSessionManager().getActor(pwmApplication); // update statistics { pwmApplication.getStatisticsManager().incrementValue(Statistic.PASSWORD_CHANGES); pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES, 1); final int passwordStrength = PasswordUtility.judgePasswordStrength(newPassword.getStringValue()); pwmApplication .getStatisticsManager() .updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH, passwordStrength); } // add the old password to the global history list (if the old password is known) if (oldPassword != null && pwmApplication .getConfig() .readSettingAsBoolean(PwmSetting.PASSWORD_SHAREDHISTORY_ENABLE)) { pwmApplication.getSharedHistoryManager().addWord(pwmSession, oldPassword.getStringValue()); } // invoke post password change actions invokePostChangePasswordActions(pwmSession, newPassword.getStringValue()); { // execute configured actions LOGGER.debug(pwmSession, "executing configured actions to user " + proxiedUser.getEntryDN()); final List<ActionConfiguration> configValues = pwmApplication .getConfig() .readSettingAsAction(PwmSetting.CHANGE_PASSWORD_WRITE_ATTRIBUTES); if (configValues != null && !configValues.isEmpty()) { final LoginInfoBean clonedLoginInfoBean = JsonUtil.cloneUsingJson(pwmSession.getLoginInfoBean(), LoginInfoBean.class); clonedLoginInfoBean.setUserCurrentPassword(newPassword); final MacroMachine macroMachine = new MacroMachine( pwmApplication, pwmSession.getLabel(), pwmSession.getUserInfoBean(), clonedLoginInfoBean, pwmSession.getSessionManager().getUserDataReader(pwmApplication)); final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, uiBean.getUserIdentity()) .setMacroMachine(macroMachine) .setExpandPwmMacros(true) .createActionExecutor(); actionExecutor.executeActions(configValues, pwmSession); } } // update the current last password update field in ldap LdapOperationsHelper.updateLastPasswordUpdateAttribute( pwmApplication, pwmSession.getLabel(), uiBean.getUserIdentity()); }
public static PasswordCheckInfo checkEnteredPassword( final PwmApplication pwmApplication, final Locale locale, final ChaiUser user, final UserInfoBean userInfoBean, final LoginInfoBean loginInfoBean, final PasswordData password, final PasswordData confirmPassword) throws PwmUnrecoverableException, ChaiUnavailableException { if (userInfoBean == null) { throw new NullPointerException("userInfoBean cannot be null"); } boolean pass = false; String userMessage = ""; int errorCode = 0; final boolean passwordIsCaseSensitive = userInfoBean.getPasswordPolicy() == null || userInfoBean .getPasswordPolicy() .getRuleHelper() .readBooleanValue(PwmPasswordRule.CaseSensitive); final CachePolicy cachePolicy; { final long cacheLifetimeMS = Long.parseLong( pwmApplication .getConfig() .readAppProperty(AppProperty.CACHE_PWRULECHECK_LIFETIME_MS)); cachePolicy = CachePolicy.makePolicyWithExpirationMS(cacheLifetimeMS); } if (password == null) { userMessage = new ErrorInformation(PwmError.PASSWORD_MISSING) .toUserStr(locale, pwmApplication.getConfig()); } else { final CacheService cacheService = pwmApplication.getCacheService(); final CacheKey cacheKey = user != null && userInfoBean.getUserIdentity() != null ? CacheKey.makeCacheKey( PasswordUtility.class, userInfoBean.getUserIdentity(), user.getEntryDN() + ":" + password.hash()) : null; if (pwmApplication.getConfig().isDevDebugMode()) { LOGGER.trace("generated cacheKey for password check request: " + cacheKey); } try { if (cacheService != null && cacheKey != null) { final String cachedValue = cacheService.get(cacheKey); if (cachedValue != null) { if (NEGATIVE_CACHE_HIT.equals(cachedValue)) { pass = true; } else { LOGGER.trace("cache hit!"); final ErrorInformation errorInformation = JsonUtil.deserialize(cachedValue, ErrorInformation.class); throw new PwmDataValidationException(errorInformation); } } } if (!pass) { final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator( pwmApplication, userInfoBean.getPasswordPolicy(), locale); final PasswordData oldPassword = loginInfoBean == null ? null : loginInfoBean.getUserCurrentPassword(); pwmPasswordRuleValidator.testPassword(password, oldPassword, userInfoBean, user); pass = true; if (cacheService != null && cacheKey != null) { cacheService.put(cacheKey, cachePolicy, NEGATIVE_CACHE_HIT); } } } catch (PwmDataValidationException e) { errorCode = e.getError().getErrorCode(); userMessage = e.getErrorInformation().toUserStr(locale, pwmApplication.getConfig()); pass = false; if (cacheService != null && cacheKey != null) { final String jsonPayload = JsonUtil.serialize(e.getErrorInformation()); cacheService.put(cacheKey, cachePolicy, jsonPayload); } } } final PasswordCheckInfo.MATCH_STATUS matchStatus = figureMatchStatus(passwordIsCaseSensitive, password, confirmPassword); if (pass) { switch (matchStatus) { case EMPTY: userMessage = new ErrorInformation(PwmError.PASSWORD_MISSING_CONFIRM) .toUserStr(locale, pwmApplication.getConfig()); break; case MATCH: userMessage = new ErrorInformation(PwmError.PASSWORD_MEETS_RULES) .toUserStr(locale, pwmApplication.getConfig()); break; case NO_MATCH: userMessage = new ErrorInformation(PwmError.PASSWORD_DOESNOTMATCH) .toUserStr(locale, pwmApplication.getConfig()); break; default: userMessage = ""; } } final int strength = judgePasswordStrength(password == null ? null : password.getStringValue()); return new PasswordCheckInfo(userMessage, pass, strength, matchStatus, errorCode); }
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); } }