Search in sources :

Example 11 with TimeDuration

use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.

the class DataStoreRecordStore method cleanup.

@Override
public void cleanup(final TimeDuration maxRecordAge) {
    if (TimeDuration.fromCurrent(eldestRecord).isShorterThan(maxRecordAge)) {
        return;
    }
    eldestRecord = Instant.now();
    final long startTime = System.currentTimeMillis();
    final int recordsExamined = 0;
    int recordsRemoved = 0;
    boolean complete = false;
    while (!complete && intruderManager.status() == PwmService.STATUS.OPEN) {
        final List<String> recordsToRemove = discoverPurgableKeys(maxRecordAge);
        if (recordsToRemove.isEmpty()) {
            complete = true;
        }
        try {
            for (final String key : recordsToRemove) {
                dataStore.remove(key);
            }
        } catch (PwmException e) {
            LOGGER.error("unable to perform removal of identified stale records: " + e.getMessage());
        }
        recordsRemoved += recordsToRemove.size();
        recordsToRemove.clear();
    }
    final TimeDuration totalDuration = TimeDuration.fromCurrent(startTime);
    LOGGER.trace("completed cleanup of intruder table in " + totalDuration.asCompactString() + ", recordsExamined=" + recordsExamined + ", recordsRemoved=" + recordsRemoved);
}
Also used : PwmException(password.pwm.error.PwmException) TimeDuration(password.pwm.util.java.TimeDuration)

Example 12 with TimeDuration

use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.

the class UserInfoReader method getPasswordStatus.

@Override
public PasswordStatus getPasswordStatus() throws PwmUnrecoverableException {
    final Configuration config = pwmApplication.getConfig();
    final PasswordStatus.PasswordStatusBuilder passwordStatusBuilder = PasswordStatus.builder();
    final String userDN = chaiUser.getEntryDN();
    final PwmPasswordPolicy passwordPolicy = selfCachedReference.getPasswordPolicy();
    final long startTime = System.currentTimeMillis();
    LOGGER.trace(sessionLabel, "beginning password status check process for " + userDN);
    // check if password meets existing policy.
    if (passwordPolicy.getRuleHelper().readBooleanValue(PwmPasswordRule.EnforceAtLogin)) {
        if (currentPassword != null) {
            try {
                final PwmPasswordRuleValidator passwordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, passwordPolicy);
                passwordRuleValidator.testPassword(currentPassword, null, selfCachedReference, chaiUser);
            } catch (PwmDataValidationException | PwmUnrecoverableException e) {
                LOGGER.debug(sessionLabel, "user " + userDN + " password does not conform to current password policy (" + e.getMessage() + "), marking as requiring change.");
                passwordStatusBuilder.violatesPolicy(true);
            } catch (ChaiUnavailableException e) {
                throw PwmUnrecoverableException.fromChaiException(e);
            }
        }
    }
    boolean ldapPasswordExpired = false;
    try {
        ldapPasswordExpired = chaiUser.isPasswordExpired();
        if (ldapPasswordExpired) {
            LOGGER.trace(sessionLabel, "password for " + userDN + " appears to be expired");
        } else {
            LOGGER.trace(sessionLabel, "password for " + userDN + " does not appear to be expired");
        }
    } catch (ChaiOperationException e) {
        LOGGER.info(sessionLabel, "error reading LDAP attributes for " + userDN + " while reading isPasswordExpired(): " + e.getMessage());
    } catch (ChaiUnavailableException e) {
        throw PwmUnrecoverableException.fromChaiException(e);
    }
    final Instant ldapPasswordExpirationTime = selfCachedReference.getPasswordExpirationTime();
    boolean preExpired = false;
    if (ldapPasswordExpirationTime != null) {
        final TimeDuration expirationInterval = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
        LOGGER.trace(sessionLabel, "read password expiration time: " + JavaHelper.toIsoDate(ldapPasswordExpirationTime) + ", " + expirationInterval.asCompactString() + " from now");
        final TimeDuration diff = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
        // now check to see if the user's expire time is within the 'preExpireTime' setting.
        final long preExpireMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_PRE_TIME) * 1000;
        if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preExpireMs) {
            LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as pre-expired");
            preExpired = true;
        } else if (ldapPasswordExpired) {
            preExpired = true;
            LOGGER.debug(sessionLabel, "user " + userDN + " password is expired, marking as pre-expired.");
        }
        // now check to see if the user's expire time is within the 'preWarnTime' setting.
        final long preWarnMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_WARN_TIME) * 1000;
        // don't check if the 'preWarnTime' setting is zero or less than the expirePreTime
        if (!ldapPasswordExpired && !preExpired) {
            if (!(preWarnMs == 0 || preWarnMs < preExpireMs)) {
                if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preWarnMs) {
                    LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as within warn period");
                    passwordStatusBuilder.warnPeriod(true);
                }
            }
        }
        passwordStatusBuilder.preExpired(preExpired);
    }
    LOGGER.debug(sessionLabel, "completed user password status check for " + userDN + " " + passwordStatusBuilder + " (" + TimeDuration.fromCurrent(startTime).asCompactString() + ")");
    passwordStatusBuilder.expired(ldapPasswordExpired);
    return passwordStatusBuilder.build();
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) FormConfiguration(password.pwm.config.value.data.FormConfiguration) Configuration(password.pwm.config.Configuration) Instant(java.time.Instant) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmPasswordRuleValidator(password.pwm.util.PwmPasswordRuleValidator) PwmDataValidationException(password.pwm.error.PwmDataValidationException) PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) PasswordStatus(password.pwm.bean.PasswordStatus) TimeDuration(password.pwm.util.java.TimeDuration) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException)

Example 13 with TimeDuration

use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.

the class IntruderManager method init.

@Override
@SuppressWarnings("checkstyle:MethodLength")
public void init(final PwmApplication pwmApplication) throws PwmException {
    this.pwmApplication = pwmApplication;
    final Configuration config = pwmApplication.getConfig();
    status = STATUS.OPENING;
    if (pwmApplication.getLocalDB() == null || pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "unable to start IntruderManager, LocalDB unavailable");
        LOGGER.error(errorInformation.toDebugStr());
        startupError = errorInformation;
        status = STATUS.CLOSED;
        return;
    }
    if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.INTRUDER_ENABLE)) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "intruder module not enabled");
        LOGGER.debug(errorInformation.toDebugStr());
        status = STATUS.CLOSED;
        return;
    }
    final DataStore dataStore;
    {
        final IntruderStorageMethod intruderStorageMethod = pwmApplication.getConfig().readSettingAsEnum(PwmSetting.INTRUDER_STORAGE_METHOD, IntruderStorageMethod.class);
        final String debugMsg;
        final DataStorageMethod storageMethodUsed;
        switch(intruderStorageMethod) {
            case AUTO:
                dataStore = DataStoreFactory.autoDbOrLocalDBstore(pwmApplication, DatabaseTable.INTRUDER, LocalDB.DB.INTRUDER);
                if (dataStore instanceof DatabaseDataStore) {
                    debugMsg = "starting using auto-configured data store, Remote Database selected";
                    storageMethodUsed = DataStorageMethod.DB;
                } else {
                    debugMsg = "starting using auto-configured data store, LocalDB selected";
                    storageMethodUsed = DataStorageMethod.LOCALDB;
                }
                break;
            case DATABASE:
                dataStore = new DatabaseDataStore(pwmApplication.getDatabaseService(), DatabaseTable.INTRUDER);
                debugMsg = "starting using Remote Database data store";
                storageMethodUsed = DataStorageMethod.DB;
                break;
            case LOCALDB:
                dataStore = new LocalDBDataStore(pwmApplication.getLocalDB(), LocalDB.DB.INTRUDER);
                debugMsg = "starting using LocalDB data store";
                storageMethodUsed = DataStorageMethod.LOCALDB;
                break;
            default:
                startupError = new ErrorInformation(PwmError.ERROR_UNKNOWN, "unknown storageMethod selected: " + intruderStorageMethod);
                status = STATUS.CLOSED;
                return;
        }
        LOGGER.info(debugMsg);
        serviceInfo = new ServiceInfoBean(Collections.singletonList(storageMethodUsed));
    }
    final RecordStore recordStore;
    {
        recordStore = new DataStoreRecordStore(dataStore, this);
        final String threadName = JavaHelper.makeThreadName(pwmApplication, this.getClass()) + " timer";
        timer = new Timer(threadName, true);
        final long maxRecordAge = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.INTRUDER_RETENTION_TIME_MS));
        final long cleanerRunFrequency = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.INTRUDER_CLEANUP_FREQUENCY_MS));
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                try {
                    recordStore.cleanup(new TimeDuration(maxRecordAge));
                } catch (Exception e) {
                    LOGGER.error("error cleaning recordStore: " + e.getMessage(), e);
                }
            }
        }, 1000, cleanerRunFrequency);
    }
    try {
        {
            final IntruderSettings settings = new IntruderSettings();
            settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_USER_MAX_ATTEMPTS));
            settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_USER_RESET_TIME)));
            settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_USER_CHECK_TIME)));
            if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
                LOGGER.info("intruder user checking will remain disabled due to configuration settings");
            } else {
                recordManagers.put(RecordType.USERNAME, new RecordManagerImpl(RecordType.USERNAME, recordStore, settings));
                recordManagers.put(RecordType.USER_ID, new RecordManagerImpl(RecordType.USER_ID, recordStore, settings));
            }
        }
        {
            final IntruderSettings settings = new IntruderSettings();
            settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_MAX_ATTEMPTS));
            settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_RESET_TIME)));
            settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ATTRIBUTE_CHECK_TIME)));
            if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
                LOGGER.info("intruder user checking will remain disabled due to configuration settings");
            } else {
                recordManagers.put(RecordType.ATTRIBUTE, new RecordManagerImpl(RecordType.ATTRIBUTE, recordStore, settings));
            }
        }
        {
            final IntruderSettings settings = new IntruderSettings();
            settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_MAX_ATTEMPTS));
            settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_RESET_TIME)));
            settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_TOKEN_DEST_CHECK_TIME)));
            if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
                LOGGER.info("intruder user checking will remain disabled due to configuration settings");
            } else {
                recordManagers.put(RecordType.TOKEN_DEST, new RecordManagerImpl(RecordType.TOKEN_DEST, recordStore, settings));
            }
        }
        {
            final IntruderSettings settings = new IntruderSettings();
            settings.setCheckCount((int) config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_MAX_ATTEMPTS));
            settings.setResetDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_RESET_TIME)));
            settings.setCheckDuration(new TimeDuration(1000 * config.readSettingAsLong(PwmSetting.INTRUDER_ADDRESS_CHECK_TIME)));
            if (settings.getCheckCount() == 0 || settings.getCheckDuration().getTotalMilliseconds() == 0 || settings.getResetDuration().getTotalMilliseconds() == 0) {
                LOGGER.info("intruder address checking will remain disabled due to configuration settings");
            } else {
                recordManagers.put(RecordType.ADDRESS, new RecordManagerImpl(RecordType.ADDRESS, recordStore, settings));
            }
        }
        status = STATUS.OPEN;
    } catch (Exception e) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "unexpected error starting intruder manager: " + e.getMessage());
        LOGGER.error(errorInformation.toDebugStr());
        startupError = errorInformation;
        close();
    }
}
Also used : FormConfiguration(password.pwm.config.value.data.FormConfiguration) Configuration(password.pwm.config.Configuration) DataStorageMethod(password.pwm.config.option.DataStorageMethod) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmException(password.pwm.error.PwmException) ErrorInformation(password.pwm.error.ErrorInformation) LocalDBDataStore(password.pwm.util.localdb.LocalDBDataStore) DatabaseDataStore(password.pwm.util.db.DatabaseDataStore) Timer(java.util.Timer) TimerTask(java.util.TimerTask) DataStore(password.pwm.util.DataStore) LocalDBDataStore(password.pwm.util.localdb.LocalDBDataStore) DatabaseDataStore(password.pwm.util.db.DatabaseDataStore) IntruderStorageMethod(password.pwm.config.option.IntruderStorageMethod) TimeDuration(password.pwm.util.java.TimeDuration)

Example 14 with TimeDuration

use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.

the class PwNotifyEngine method executeJob.

void executeJob() throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException, PwmUnrecoverableException {
    startTime = Instant.now();
    examinedCount = 0;
    noticeCount = 0;
    try {
        internalLog.delete(0, internalLog.length());
        running = true;
        if (!canRunOnThisServer()) {
            return;
        }
        if (JavaHelper.isEmpty(permissionList)) {
            log("no users are included in permission list setting " + PwmSetting.PW_EXPY_NOTIFY_PERMISSION.toMenuLocationDebug(null, null) + ", exiting.");
            return;
        }
        log("starting job, beginning ldap search");
        final Iterator<UserIdentity> workQueue = LdapOperationsHelper.readAllUsersFromLdap(pwmApplication, null, null, settings.getMaxLdapSearchSize());
        log("ldap search complete, examining users...");
        while (workQueue.hasNext()) {
            if (!checkIfRunningOnMaster()) {
                final String msg = "job interrupted, server is no longer the cluster master.";
                log(msg);
                throw PwmUnrecoverableException.newException(PwmError.ERROR_SERVICE_NOT_AVAILABLE, msg);
            }
            checkIfRunningOnMaster();
            examinedCount++;
            final List<UserIdentity> batch = new ArrayList<>();
            final int batchSize = settings.getBatchCount();
            while (batch.size() < batchSize && workQueue.hasNext()) {
                batch.add(workQueue.next());
            }
            final Instant startBatch = Instant.now();
            examinedCount += batch.size();
            noticeCount += processBatch(batch);
            eventRateMeter.markEvents(batchSize);
            final TimeDuration batchTime = TimeDuration.fromCurrent(startBatch);
            final TimeDuration pauseTime = new TimeDuration(settings.getBatchTimeMultiplier().multiply(new BigDecimal(batchTime.getTotalMilliseconds())).longValue(), TimeUnit.MILLISECONDS);
            pauseTime.pause();
            debugOutputTask.conditionallyExecuteTask();
        }
        log("job complete, " + examinedCount + " users evaluated in " + TimeDuration.fromCurrent(startTime).asCompactString() + ", sent " + noticeCount + " notices.");
    } finally {
        running = false;
    }
}
Also used : UserIdentity(password.pwm.bean.UserIdentity) Instant(java.time.Instant) ArrayList(java.util.ArrayList) TimeDuration(password.pwm.util.java.TimeDuration) BigDecimal(java.math.BigDecimal)

Example 15 with TimeDuration

use of password.pwm.util.java.TimeDuration in project pwm by pwm-project.

the class PasswordUtility method isPasswordWithinMinimumLifetimeImpl.

public static boolean isPasswordWithinMinimumLifetimeImpl(final ChaiUser chaiUser, final SessionLabel sessionLabel, final PwmPasswordPolicy passwordPolicy, final Instant lastModified, final PasswordStatus passwordStatus) throws PwmUnrecoverableException {
    // for oracle DS; this check is also handled in UserAuthenticator.
    try {
        if (DirectoryVendor.ORACLE_DS == chaiUser.getChaiProvider().getDirectoryVendor()) {
            final String oracleDSPrePasswordAllowChangeTime = chaiUser.readStringAttribute("passwordAllowChangeTime");
            if (oracleDSPrePasswordAllowChangeTime != null && !oracleDSPrePasswordAllowChangeTime.isEmpty()) {
                final Instant date = OracleDSEntries.convertZuluToDate(oracleDSPrePasswordAllowChangeTime);
                if (Instant.now().isBefore(date)) {
                    LOGGER.debug("discovered oracleds allowed change time is set to: " + JavaHelper.toIsoDate(date) + ", won't permit password change");
                    final String errorMsg = "change not permitted until " + JavaHelper.toIsoDate(date);
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.PASSWORD_TOO_SOON, errorMsg);
                    throw new PwmUnrecoverableException(errorInformation);
                }
            }
            return false;
        }
    } catch (ChaiException e) {
        LOGGER.debug(sessionLabel, "unexpected error reading OracleDS password allow modification time: " + e.getMessage());
    }
    final TimeDuration minimumLifetime;
    {
        final int minimumLifetimeSeconds = passwordPolicy.getRuleHelper().readIntValue(PwmPasswordRule.MinimumLifetime);
        if (minimumLifetimeSeconds < 1) {
            return false;
        }
        if (lastModified == null) {
            LOGGER.debug(sessionLabel, "skipping minimum lifetime check, password last set time is unknown");
            return false;
        }
        minimumLifetime = new TimeDuration(minimumLifetimeSeconds, TimeUnit.SECONDS);
    }
    final TimeDuration passwordAge = TimeDuration.fromCurrent(lastModified);
    LOGGER.trace(sessionLabel, "beginning check for minimum lifetime, lastModified=" + JavaHelper.toIsoDate(lastModified) + ", minimumLifetimeSeconds=" + minimumLifetime.asCompactString() + ", passwordAge=" + passwordAge.asCompactString());
    if (lastModified.isAfter(Instant.now())) {
        LOGGER.debug(sessionLabel, "skipping minimum lifetime check, password lastModified time is in the future");
        return false;
    }
    final boolean passwordTooSoon = passwordAge.isShorterThan(minimumLifetime);
    if (!passwordTooSoon) {
        LOGGER.trace(sessionLabel, "minimum lifetime check passed, password age ");
        return false;
    }
    if (passwordStatus.isExpired() || passwordStatus.isPreExpired() || passwordStatus.isWarnPeriod()) {
        LOGGER.debug(sessionLabel, "current password is too young, but skipping enforcement of minimum lifetime check because current password is expired");
        return false;
    }
    return true;
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) Instant(java.time.Instant) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) TimeDuration(password.pwm.util.java.TimeDuration) ChaiException(com.novell.ldapchai.exception.ChaiException)

Aggregations

TimeDuration (password.pwm.util.java.TimeDuration)75 Instant (java.time.Instant)28 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)22 ErrorInformation (password.pwm.error.ErrorInformation)19 PwmException (password.pwm.error.PwmException)14 ArrayList (java.util.ArrayList)12 LinkedHashMap (java.util.LinkedHashMap)12 IOException (java.io.IOException)9 Configuration (password.pwm.config.Configuration)8 PwmOperationalException (password.pwm.error.PwmOperationalException)8 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)7 Map (java.util.Map)7 UserIdentity (password.pwm.bean.UserIdentity)7 HashMap (java.util.HashMap)6 HashSet (java.util.HashSet)6 List (java.util.List)6 MacroMachine (password.pwm.util.macro.MacroMachine)6 BigDecimal (java.math.BigDecimal)5 Date (java.util.Date)5 Locale (java.util.Locale)5