Beispiel #1
0
 private void updateCacheFromLdap()
     throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException,
         PwmUnrecoverableException {
   LOGGER.debug(
       PwmConstants.REPORTING_SESSION_LABEL,
       "beginning process to updating user cache records from ldap");
   if (status != STATUS.OPEN) {
     return;
   }
   cancelFlag = false;
   reportStatus = new ReportStatusInfo(settings.getSettingsHash());
   reportStatus.setInProgress(true);
   reportStatus.setStartDate(new Date());
   try {
     final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers());
     reportStatus.setTotal(allUsers.size());
     while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) {
       final Date startUpdateTime = new Date();
       final UserIdentity userIdentity = allUsers.poll();
       try {
         if (updateCachedRecordFromLdap(userIdentity)) {
           reportStatus.setUpdated(reportStatus.getUpdated() + 1);
         }
       } catch (Exception e) {
         String errorMsg =
             "error while updating report cache for " + userIdentity.toString() + ", cause: ";
         errorMsg +=
             e instanceof PwmException
                 ? ((PwmException) e).getErrorInformation().toDebugStr()
                 : e.getMessage();
         final ErrorInformation errorInformation;
         errorInformation = new ErrorInformation(PwmError.ERROR_REPORTING_ERROR, errorMsg);
         LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, errorInformation.toDebugStr());
         reportStatus.setLastError(errorInformation);
         reportStatus.setErrors(reportStatus.getErrors() + 1);
       }
       reportStatus.setCount(reportStatus.getCount() + 1);
       reportStatus.getEventRateMeter().markEvents(1);
       final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime);
       if (settings.isAutoCalcRest()) {
         avgTracker.addSample(totalUpdateTime.getTotalMilliseconds());
         Helper.pause(avgTracker.avgAsLong());
       } else {
         Helper.pause(settings.getRestTime().getTotalMilliseconds());
       }
     }
     if (cancelFlag) {
       reportStatus.setLastError(
           new ErrorInformation(
               PwmError.ERROR_SERVICE_NOT_AVAILABLE, "report cancelled by operator"));
     }
   } finally {
     reportStatus.setFinishDate(new Date());
     reportStatus.setInProgress(false);
   }
   LOGGER.debug(
       PwmConstants.REPORTING_SESSION_LABEL,
       "update user cache process completed: " + JsonUtil.serialize(reportStatus));
 }
Beispiel #2
0
 public UserCacheRecord next() {
   try {
     UserCacheRecord returnBean = null;
     while (returnBean == null && this.storageKeyIterator.hasNext()) {
       UserCacheService.StorageKey key = this.storageKeyIterator.next();
       returnBean = userCacheService.readStorageKey(key);
       if (returnBean != null) {
         if (returnBean.getCacheTimestamp() == null) {
           LOGGER.debug(
               PwmConstants.REPORTING_SESSION_LABEL,
               "purging record due to missing cache timestamp: "
                   + JsonUtil.serialize(returnBean));
           userCacheService.removeStorageKey(key);
         } else if (TimeDuration.fromCurrent(returnBean.getCacheTimestamp())
             .isLongerThan(settings.getMaxCacheAge())) {
           LOGGER.debug(
               PwmConstants.REPORTING_SESSION_LABEL,
               "purging record due to old age timestamp: " + JsonUtil.serialize(returnBean));
           userCacheService.removeStorageKey(key);
         } else {
           return returnBean;
         }
       }
     }
   } catch (LocalDBException e) {
     throw new IllegalStateException(
         "unexpected iterator traversal error while reading LocalDB: " + e.getMessage());
   }
   return null;
 }
Beispiel #3
0
 @Override
 public void run() {
   try {
     initTempData();
   } catch (LocalDBException | PwmUnrecoverableException e) {
     LOGGER.error(
         PwmConstants.REPORTING_SESSION_LABEL, "error during initialization: " + e.getMessage());
     status = STATUS.CLOSED;
     return;
   }
   final long secondsUntilNextDredge =
       settings.getJobOffsetSeconds()
           + TimeDuration.fromCurrent(Helper.nextZuluZeroTime()).getTotalSeconds();
   executorService.scheduleAtFixedRate(
       new DredgeTask(),
       secondsUntilNextDredge,
       TimeDuration.DAY.getTotalSeconds(),
       TimeUnit.SECONDS);
   executorService.scheduleAtFixedRate(
       new RolloverTask(),
       secondsUntilNextDredge + 1,
       TimeDuration.DAY.getTotalSeconds(),
       TimeUnit.SECONDS);
   executorService.submit(new RolloverTask());
 }
Beispiel #4
0
  private void restBrowseLdap(final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean)
      throws IOException, ServletException, PwmUnrecoverableException {
    final StoredConfigurationImpl storedConfiguration =
        StoredConfigurationImpl.copy(configGuideBean.getStoredConfiguration());
    if (configGuideBean.getStep() == STEP.LDAP_ADMIN) {
      storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE_KEY, null);
      storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE_KEY, null);
    }

    final Date startTime = new Date();
    final Map<String, String> inputMap =
        pwmRequest.readBodyAsJsonStringMap(PwmHttpRequestWrapper.Flag.BypassValidation);
    final String profile = inputMap.get("profile");
    final String dn = inputMap.containsKey("dn") ? inputMap.get("dn") : "";

    final LdapBrowser ldapBrowser = new LdapBrowser(storedConfiguration);
    final LdapBrowser.LdapBrowseResult result = ldapBrowser.doBrowse(profile, dn);
    ldapBrowser.close();

    LOGGER.trace(
        pwmRequest,
        "performed ldapBrowse operation in "
            + TimeDuration.fromCurrent(startTime).asCompactString()
            + ", result="
            + JsonUtil.serialize(result));

    pwmRequest.outputJsonResult(new RestResultBean(result));
  }
Beispiel #5
0
  @Override
  void closeConnection(final Connection connection) throws SQLException {

    if (aggressiveCompact) {
      CallableStatement statement = null;
      try {
        LOCK.writeLock().lock();
        final java.util.Date start = new java.util.Date();
        LOGGER.trace("beginning shutdown compact");
        statement = dbConnection.prepareCall("SHUTDOWN COMPACT");
        statement.execute();
        LOGGER.trace(
            "completed shutdown compact in " + TimeDuration.fromCurrent(start).asCompactString());
      } catch (SQLException ex) {
        LOGGER.error("error during shutdown compact: " + ex.getMessage());
      } finally {
        close(statement);
        LOCK.writeLock().unlock();
      }
    }

    try {
      connection.close();
      if (driver != null) {
        DriverManager.deregisterDriver(driver);
        driver = null;
      }
    } catch (Exception e) {
      LOGGER.error("error during H2 shutdown: " + e.getMessage());
    }
  }
Beispiel #6
0
  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());
  }
Beispiel #8
0
 public void clear() throws LocalDBException, PwmUnrecoverableException {
   final Date startTime = new Date();
   LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL, "clearing cached report data");
   if (userCacheService != null) {
     userCacheService.clear();
   }
   summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays());
   reportStatus = new ReportStatusInfo(settings.getSettingsHash());
   saveTempData();
   LOGGER.info(
       PwmConstants.REPORTING_SESSION_LABEL,
       "finished clearing report " + TimeDuration.fromCurrent(startTime).asCompactString());
 }
Beispiel #9
0
  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);
    }
  }
Beispiel #10
0
 private LocalDBLoggerSettings(
     final int maxEvents,
     final TimeDuration maxAge,
     final Set<Flag> flags,
     final int maxBufferSize,
     final TimeDuration maxBufferWaitTime,
     final int maxTrimSize) {
   this.maxEvents = maxEvents < 1 ? 0 : Math.max(MINIMUM_MAXIMUM_EVENTS, maxEvents);
   this.maxAge =
       maxAge == null || maxAge.isShorterThan(MINIMUM_MAX_AGE) ? MINIMUM_MAX_AGE : maxAge;
   this.flags = flags == null ? Collections.<Flag>emptySet() : Collections.unmodifiableSet(flags);
   this.maxBufferSize = maxBufferSize;
   this.maxBufferWaitTime = maxBufferWaitTime;
   this.maxTrimSize = maxTrimSize;
 }
Beispiel #11
0
  public int outputStatsToCsv(
      final OutputStream outputStream, final Locale locale, final boolean includeHeader)
      throws IOException {
    LOGGER.trace("beginning output stats to csv process");
    final Date startTime = new Date();

    final StatisticsManager statsManger = pwmApplication.getStatisticsManager();
    final CSVPrinter csvPrinter = Helper.makeCsvPrinter(outputStream);

    if (includeHeader) {
      final List<String> headers = new ArrayList<>();
      headers.add("KEY");
      headers.add("YEAR");
      headers.add("DAY");
      for (Statistic stat : Statistic.values()) {
        headers.add(stat.getLabel(locale));
      }
      csvPrinter.printRecord(headers);
    }

    int counter = 0;
    final Map<StatisticsManager.DailyKey, String> keys =
        statsManger.getAvailableKeys(PwmConstants.DEFAULT_LOCALE);
    for (final StatisticsManager.DailyKey loopKey : keys.keySet()) {
      counter++;
      final StatisticsBundle bundle = statsManger.getStatBundleForKey(loopKey.toString());
      final List<String> lineOutput = new ArrayList<>();
      lineOutput.add(loopKey.toString());
      lineOutput.add(String.valueOf(loopKey.year));
      lineOutput.add(String.valueOf(loopKey.day));
      for (final Statistic stat : Statistic.values()) {
        lineOutput.add(bundle.getStatistic(stat));
      }
      csvPrinter.printRecord(lineOutput);
    }

    csvPrinter.flush();
    LOGGER.trace(
        "completed output stats to csv process; output "
            + counter
            + " records in "
            + TimeDuration.fromCurrent(startTime).asCompactString());
    return counter;
  }
Beispiel #12
0
  private void updateRestingCacheData() {
    final long startTime = System.currentTimeMillis();
    int examinedRecords = 0;
    ClosableIterator<UserCacheRecord> iterator = null;
    try {
      LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL, "checking size of stored cache records");
      final int totalRecords = userCacheService.size();
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "beginning cache review process of " + totalRecords + " records");
      iterator = iterator();
      Date lastLogOutputTime = new Date();
      while (iterator.hasNext() && status == STATUS.OPEN) {
        final UserCacheRecord record = iterator.next(); // (purge routine is embedded in next();

        if (summaryData != null && record != null) {
          summaryData.update(record);
        }

        examinedRecords++;

        if (TimeDuration.fromCurrent(lastLogOutputTime).isLongerThan(30, TimeUnit.SECONDS)) {
          final TimeDuration progressDuration = TimeDuration.fromCurrent(startTime);
          LOGGER.trace(
              PwmConstants.REPORTING_SESSION_LABEL,
              "cache review process in progress, examined "
                  + examinedRecords
                  + " records in "
                  + progressDuration.asCompactString());
          lastLogOutputTime = new Date();
        }
      }
      final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "completed cache review process of "
              + examinedRecords
              + " cached report records in "
              + totalTime.asCompactString());
    } finally {
      if (iterator != null) {
        iterator.close();
      }
    }
  }
Beispiel #13
0
  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;
  }
Beispiel #14
0
 public int compareTo(final Object o) {
   final TimeDuration td = (TimeDuration) o;
   final long otherMS = td.getTotalMilliseconds();
   return (ms == otherMS ? 0 : (ms < otherMS ? -1 : 1));
 }
Beispiel #15
0
 public TimeDuration subtract(final TimeDuration duration) {
   return new TimeDuration(
       Math.abs(this.getTotalMilliseconds() - duration.getTotalMilliseconds()));
 }
  private void init(final PwmApplication pwmApplication, final long maxAgeMs) {
    status = STATUS.OPENING;
    final long startTime = System.currentTimeMillis();

    try {
      checkDbVersion();
    } catch (Exception e) {
      LOGGER.error("error checking db version", e);
      status = STATUS.CLOSED;
      return;
    }

    try {
      final String oldestEntryStr = localDB.get(META_DB, KEY_OLDEST_ENTRY);
      if (oldestEntryStr == null || oldestEntryStr.length() < 1) {
        oldestEntry = 0;
        LOGGER.trace("no oldestEntry timestamp stored, will rescan");
      } else {
        oldestEntry = Long.parseLong(oldestEntryStr);
        LOGGER.trace(
            "oldest timestamp loaded from localDB, age is "
                + TimeDuration.fromCurrent(oldestEntry).asCompactString());
      }
    } catch (LocalDBException e) {
      LOGGER.error(
          "unexpected error loading oldest-entry meta record, will remain closed: "
              + e.getMessage(),
          e);
      status = STATUS.CLOSED;
      return;
    }

    try {
      final int size = localDB.size(WORDS_DB);
      final StringBuilder sb = new StringBuilder();
      sb.append("open with ").append(size).append(" words (");
      sb.append(new TimeDuration(System.currentTimeMillis(), startTime).asCompactString())
          .append(")");
      sb.append(", maxAgeMs=").append(new TimeDuration(maxAgeMs).asCompactString());
      sb.append(", oldestEntry=")
          .append(new TimeDuration(System.currentTimeMillis(), oldestEntry).asCompactString());
      LOGGER.info(sb.toString());
    } catch (LocalDBException e) {
      LOGGER.error(
          "unexpected error examining size of DB, will remain closed: " + e.getMessage(), e);
      status = STATUS.CLOSED;
      return;
    }

    status = STATUS.OPEN;
    // populateFromWordlist();  //only used for debugging!!!

    if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING
        || pwmApplication.getApplicationMode() == PwmApplication.MODE.CONFIGURATION) {
      long frequencyMs = maxAgeMs > MAX_CLEANER_FREQUENCY ? MAX_CLEANER_FREQUENCY : maxAgeMs;
      frequencyMs = frequencyMs < MIN_CLEANER_FREQUENCY ? MIN_CLEANER_FREQUENCY : frequencyMs;

      LOGGER.debug(
          "scheduling cleaner task to run once every "
              + new TimeDuration(frequencyMs).asCompactString());
      final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer";
      cleanerTimer = new Timer(threadName, true);
      cleanerTimer.schedule(new CleanerTask(), 1000, frequencyMs);
    }
  }
Beispiel #17
0
 public TimeDuration add(final TimeDuration duration) {
   return new TimeDuration(this.getTotalMilliseconds() + duration.getTotalMilliseconds());
 }
  @Override
  void doCommand() throws Exception {
    final PwmApplication pwmApplication = cliEnvironment.getPwmApplication();

    final File inputFile =
        (File)
            cliEnvironment.getOptions().get(CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName());
    final BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                new FileInputStream(inputFile), PwmConstants.DEFAULT_CHARSET.toString()));
    out("importing stored responses from " + inputFile.getAbsolutePath() + "....");

    int counter = 0;
    String line;
    final long startTime = System.currentTimeMillis();
    while ((line = reader.readLine()) != null) {
      counter++;
      final RestChallengesServer.JsonChallengesData inputData;
      inputData = JsonUtil.deserialize(line, RestChallengesServer.JsonChallengesData.class);

      final UserIdentity userIdentity = UserIdentity.fromDelimitedKey(inputData.username);
      final ChaiUser user = pwmApplication.getProxiedChaiUser(userIdentity);
      if (user.isValid()) {
        out("writing responses to user '" + user.getEntryDN() + "'");
        try {
          final ChallengeProfile challengeProfile =
              pwmApplication
                  .getCrService()
                  .readUserChallengeProfile(
                      null,
                      userIdentity,
                      user,
                      PwmPasswordPolicy.defaultPolicy(),
                      PwmConstants.DEFAULT_LOCALE);
          final ChallengeSet challengeSet = challengeProfile.getChallengeSet();
          final String userGuid =
              LdapOperationsHelper.readLdapGuidValue(pwmApplication, null, userIdentity, false);
          final ResponseInfoBean responseInfoBean =
              inputData.toResponseInfoBean(
                  PwmConstants.DEFAULT_LOCALE, challengeSet.getIdentifier());
          pwmApplication.getCrService().writeResponses(user, userGuid, responseInfoBean);
        } catch (Exception e) {
          out(
              "error writing responses to user '"
                  + user.getEntryDN()
                  + "', error: "
                  + e.getMessage());
          return;
        }
      } else {
        out("user '" + user.getEntryDN() + "' is not a valid userDN");
        return;
      }
    }

    out(
        "output complete, "
            + counter
            + " responses imported in "
            + TimeDuration.fromCurrent(startTime).asCompactString());
  }
    private void reduceWordDB() throws LocalDBException {

      if (localDB == null || localDB.status() != LocalDB.Status.OPEN) {
        return;
      }

      final long oldestEntryAge = System.currentTimeMillis() - oldestEntry;
      if (oldestEntryAge < settings.maxAgeMs) {
        LOGGER.debug(
            "skipping wordDB reduce operation, eldestEntry="
                + TimeDuration.asCompactString(oldestEntryAge)
                + ", maxAge="
                + TimeDuration.asCompactString(settings.maxAgeMs));
        return;
      }

      final long startTime = System.currentTimeMillis();
      final int initialSize = size();
      int removeCount = 0;
      long localOldestEntry = System.currentTimeMillis();

      LOGGER.debug(
          "beginning wordDB reduce operation, examining "
              + initialSize
              + " words for entries older than "
              + TimeDuration.asCompactString(settings.maxAgeMs));

      LocalDB.LocalDBIterator<String> keyIterator = null;
      try {
        keyIterator = localDB.iterator(WORDS_DB);
        while (status == STATUS.OPEN && keyIterator.hasNext()) {
          final String key = keyIterator.next();
          final String value = localDB.get(WORDS_DB, key);
          final long timeStamp = Long.parseLong(value);
          final long entryAge = System.currentTimeMillis() - timeStamp;

          if (entryAge > settings.maxAgeMs) {
            localDB.remove(WORDS_DB, key);
            removeCount++;

            if (removeCount % 1000 == 0) {
              LOGGER.trace(
                  "wordDB reduce operation in progress, removed="
                      + removeCount
                      + ", total="
                      + (initialSize - removeCount));
            }
          } else {
            localOldestEntry = timeStamp < localOldestEntry ? timeStamp : localOldestEntry;
          }
          sleeper.sleep();
        }
      } finally {
        try {
          if (keyIterator != null) {
            keyIterator.close();
          }
        } catch (Exception e) {
          LOGGER.warn("error returning LocalDB iterator: " + e.getMessage());
        }
      }

      // update the oldest entry
      if (status == STATUS.OPEN) {
        oldestEntry = localOldestEntry;
        localDB.put(META_DB, KEY_OLDEST_ENTRY, Long.toString(oldestEntry));
      }

      final StringBuilder sb = new StringBuilder();
      sb.append("completed wordDB reduce operation");
      sb.append(", removed=").append(removeCount);
      sb.append(", totalRemaining=").append(size());
      sb.append(", oldestEntry=").append(TimeDuration.asCompactString(oldestEntry));
      sb.append(" in ")
          .append(TimeDuration.asCompactString(System.currentTimeMillis() - startTime));
      LOGGER.debug(sb.toString());
    }
Beispiel #20
0
  public List<HealthRecord> healthCheck() {
    if (status == PwmService.STATUS.CLOSED) {
      return Collections.emptyList();
    }

    final List<HealthRecord> returnRecords = new ArrayList<>();

    try {
      preOperationCheck();
    } catch (DatabaseException e) {
      lastError = e.getErrorInformation();
      returnRecords.add(
          new HealthRecord(
              HealthStatus.WARN,
              HealthTopic.Database,
              "Database server is not available: " + e.getErrorInformation().toDebugStr()));
      return returnRecords;
    }

    try {
      final Map<String, String> tempMap = new HashMap<>();
      tempMap.put("instance", instanceID);
      tempMap.put("date", (new java.util.Date()).toString());
      this.put(
          DatabaseTable.PWM_META, DatabaseAccessorImpl.KEY_TEST, JsonUtil.serializeMap(tempMap));
    } catch (PwmException e) {
      returnRecords.add(
          new HealthRecord(
              HealthStatus.WARN,
              HealthTopic.Database,
              "Error writing to database: " + e.getErrorInformation().toDebugStr()));
      return returnRecords;
    }

    if (lastError != null) {
      final TimeDuration errorAge = TimeDuration.fromCurrent(lastError.getDate().getTime());

      if (errorAge.isShorterThan(TimeDuration.HOUR)) {
        returnRecords.add(
            new HealthRecord(
                HealthStatus.CAUTION,
                HealthTopic.Database,
                "Database server was recently unavailable ("
                    + errorAge.asLongString(PwmConstants.DEFAULT_LOCALE)
                    + " ago at "
                    + lastError.getDate().toString()
                    + "): "
                    + lastError.toDebugStr()));
      }
    }

    if (returnRecords.isEmpty()) {
      returnRecords.add(
          new HealthRecord(
              HealthStatus.GOOD,
              HealthTopic.Database,
              "Database connection to " + this.dbConfiguration.getConnectionString() + " okay"));
    }

    return returnRecords;
  }
Beispiel #21
0
  private void initialize(final boolean initLogging) throws PwmUnrecoverableException {
    final Date startTime = new Date();

    // initialize log4j
    if (initLogging) {
      final String log4jFileName =
          configuration.readSettingAsString(PwmSetting.EVENTS_JAVA_LOG4JCONFIG_FILE);
      final File log4jFile = Helper.figureFilepath(log4jFileName, applicationPath);
      final String consoleLevel, fileLevel;
      switch (getApplicationMode()) {
        case ERROR:
        case NEW:
          consoleLevel = PwmLogLevel.TRACE.toString();
          fileLevel = PwmLogLevel.TRACE.toString();
          break;

        default:
          consoleLevel = configuration.readSettingAsString(PwmSetting.EVENTS_JAVA_STDOUT_LEVEL);
          fileLevel = configuration.readSettingAsString(PwmSetting.EVENTS_FILE_LEVEL);
          break;
      }

      PwmLogManager.initializeLogger(
          this, configuration, log4jFile, consoleLevel, applicationPath, fileLevel);

      switch (getApplicationMode()) {
        case RUNNING:
          break;

        case ERROR:
          LOGGER.fatal(
              "starting up in ERROR mode! Check log or health check information for cause");
          break;

        default:
          LOGGER.trace(
              "setting log level to TRACE because application mode is " + getApplicationMode());
          break;
      }
    }

    LOGGER.info(
        "initializing, application mode="
            + getApplicationMode()
            + ", applicationPath="
            + (applicationPath == null ? "null" : applicationPath.getAbsolutePath())
            + ", configurationFile="
            + (configurationFile == null ? "null" : configurationFile.getAbsolutePath()));

    this.localDB = Initializer.initializeLocalDB(this);
    this.localDBLogger = PwmLogManager.initializeLocalDBLogger(this);

    // log the loaded configuration
    LOGGER.info("configuration load completed");

    // read the pwm servlet instance id
    instanceID = fetchInstanceID(localDB, this);
    LOGGER.info("using '" + getInstanceID() + "' for instance's ID (instanceID)");

    // read the pwm installation date
    installTime = fetchInstallDate(startupTime);
    LOGGER.debug(
        "this application instance first installed on "
            + PwmConstants.DEFAULT_DATETIME_FORMAT.format(installTime));

    initServices();

    final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
    LOGGER.info(
        PwmConstants.PWM_APP_NAME
            + " "
            + PwmConstants.SERVLET_VERSION
            + " open for bidness! ("
            + totalTime.asCompactString()
            + ")");
    StatisticsManager.incrementStat(this, Statistic.PWM_STARTUPS);
    LOGGER.debug(
        "buildTime="
            + PwmConstants.BUILD_TIME
            + ", javaLocale="
            + Locale.getDefault()
            + ", DefaultLocale="
            + PwmConstants.DEFAULT_LOCALE);

    final Thread postInitThread =
        new Thread() {
          @Override
          public void run() {
            postInitTasks();
          }
        };
    postInitThread.setDaemon(true);
    postInitThread.setName(Helper.makeThreadName(this, PwmApplication.class));
    postInitThread.start();
  }
Beispiel #22
0
  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());
  }
Beispiel #23
0
  private boolean updateCachedRecordFromLdap(
      final UserIdentity userIdentity,
      final UserInfoBean userInfoBean,
      final UserCacheService.StorageKey storageKey)
      throws ChaiUnavailableException, PwmUnrecoverableException, LocalDBException {
    final UserCacheRecord userCacheRecord = userCacheService.readStorageKey(storageKey);
    TimeDuration cacheAge = null;
    if (userCacheRecord != null && userCacheRecord.getCacheTimestamp() != null) {
      cacheAge = TimeDuration.fromCurrent(userCacheRecord.getCacheTimestamp());
    }

    boolean updateCache = false;
    if (userInfoBean != null) {
      updateCache = true;
    } else {
      if (cacheAge == null) {
        LOGGER.trace(
            PwmConstants.REPORTING_SESSION_LABEL,
            "stored cache for "
                + userIdentity
                + " is missing cache storage timestamp, will update");
        updateCache = true;
      } else if (cacheAge.isLongerThan(settings.getMinCacheAge())) {
        LOGGER.trace(
            PwmConstants.REPORTING_SESSION_LABEL,
            "stored cache for "
                + userIdentity
                + " is "
                + cacheAge.asCompactString()
                + " old, will update");
        updateCache = true;
      }
    }

    if (updateCache) {
      if (userCacheRecord != null) {
        if (summaryData != null
            && summaryData.getEpoch() != null
            && summaryData.getEpoch().equals(userCacheRecord.getSummaryEpoch())) {
          summaryData.remove(userCacheRecord);
        }
      }
      final UserInfoBean newUserBean;
      if (userInfoBean != null) {
        newUserBean = userInfoBean;
      } else {
        newUserBean = new UserInfoBean();
        final UserStatusReader.Settings readerSettings = new UserStatusReader.Settings();
        readerSettings.setSkipReportUpdate(true);
        final ChaiProvider chaiProvider =
            pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID());
        final UserStatusReader userStatusReader =
            new UserStatusReader(
                pwmApplication, PwmConstants.REPORTING_SESSION_LABEL, readerSettings);
        userStatusReader.populateUserInfoBean(
            newUserBean, PwmConstants.DEFAULT_LOCALE, userIdentity, chaiProvider);
      }
      final UserCacheRecord newUserCacheRecord = userCacheService.updateUserCache(newUserBean);

      if (summaryData != null && summaryData.getEpoch() != null && newUserCacheRecord != null) {
        if (!summaryData.getEpoch().equals(newUserCacheRecord.getSummaryEpoch())) {
          newUserCacheRecord.setSummaryEpoch(summaryData.getEpoch());
          userCacheService.store(newUserCacheRecord);
        }
        summaryData.update(newUserCacheRecord);
      }
    }

    return updateCache;
  }
  private AuthenticationResult authenticateUserImpl(final PasswordData password)
      throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
    if (startTime == null) {
      startTime = new Date();
    }

    log(
        PwmLogLevel.DEBUG,
        "preparing to authenticate user using authenticationType="
            + this.requestedAuthType
            + " using strategy "
            + this.strategy);

    final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
    final IntruderManager intruderManager = pwmApplication.getIntruderManager();
    intruderManager.convenience().checkUserIdentity(userIdentity);
    intruderManager.check(RecordType.ADDRESS, sessionLabel.getSrcAddress());

    boolean allowBindAsUser = true;
    if (strategy == AuthenticationStrategy.ADMIN_PROXY) {
      allowBindAsUser = false;
    }

    if (allowBindAsUser) {
      try {
        testCredentials(userIdentity, password);
      } catch (PwmOperationalException e) {
        boolean permitAuthDespiteError = false;
        final ChaiProvider.DIRECTORY_VENDOR vendor =
            pwmApplication
                .getProxyChaiProvider(userIdentity.getLdapProfileID())
                .getDirectoryVendor();
        if (PwmError.PASSWORD_NEW_PASSWORD_REQUIRED == e.getError()) {
          if (vendor == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) {
            if (pwmApplication
                .getConfig()
                .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_REQUIRE_NEW_PWD)) {
              log(
                  PwmLogLevel.INFO,
                  "auth bind failed, but will allow login due to 'must change password on next login AD error', error: "
                      + e.getErrorInformation().toDebugStr());
              allowBindAsUser = false;
              permitAuthDespiteError = true;
            }
          } else if (vendor == ChaiProvider.DIRECTORY_VENDOR.ORACLE_DS) {
            if (pwmApplication
                .getConfig()
                .readSettingAsBoolean(PwmSetting.ORACLE_DS_ALLOW_AUTH_REQUIRE_NEW_PWD)) {
              log(
                  PwmLogLevel.INFO,
                  "auth bind failed, but will allow login due to 'pwdReset' user attribute, error: "
                      + e.getErrorInformation().toDebugStr());
              allowBindAsUser = false;
              permitAuthDespiteError = true;
            }
          }
        } else if (PwmError.PASSWORD_EXPIRED
            == e.getError()) { // handle ad case where password is expired
          if (vendor == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) {
            if (pwmApplication
                .getConfig()
                .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_REQUIRE_NEW_PWD)) {
              if (!pwmApplication
                  .getConfig()
                  .readSettingAsBoolean(PwmSetting.AD_ALLOW_AUTH_EXPIRED)) {
                throw e;
              }
              log(
                  PwmLogLevel.INFO,
                  "auth bind failed, but will allow login due to 'password expired AD error', error: "
                      + e.getErrorInformation().toDebugStr());
              allowBindAsUser = false;
              permitAuthDespiteError = true;
            }
          }
        }

        if (!permitAuthDespiteError) { // auth failed, presumably due to wrong password.
          statisticsManager.incrementValue(Statistic.AUTHENTICATION_FAILURES);
          throw e;
        }
      }
    } else {
      // verify user is not account disabled
      AuthenticationUtility.checkIfUserEligibleToAuthentication(pwmApplication, userIdentity);
    }

    statisticsManager.incrementValue(Statistic.AUTHENTICATIONS);
    statisticsManager.updateEps(Statistic.EpsType.AUTHENTICATION, 1);
    statisticsManager.updateAverageValue(
        Statistic.AVG_AUTHENTICATION_TIME,
        TimeDuration.fromCurrent(startTime).getTotalMilliseconds());

    final AuthenticationType returnAuthType;
    if (!allowBindAsUser) {
      returnAuthType = AuthenticationType.AUTH_BIND_INHIBIT;
    } else {
      if (requestedAuthType == null) {
        returnAuthType = AuthenticationType.AUTHENTICATED;
      } else {
        if (requestedAuthType == AuthenticationType.AUTH_WITHOUT_PASSWORD) {
          returnAuthType = AuthenticationType.AUTHENTICATED;
        } else if (requestedAuthType == AuthenticationType.AUTH_FROM_PUBLIC_MODULE) {
          returnAuthType = AuthenticationType.AUTH_FROM_PUBLIC_MODULE;
        } else {
          returnAuthType = requestedAuthType;
        }
      }
    }

    final boolean useProxy = determineIfLdapProxyNeeded(returnAuthType, password);
    final ChaiProvider returnProvider = useProxy ? makeProxyProvider() : userProvider;
    final AuthenticationResult authenticationResult =
        new AuthenticationResult(returnProvider, returnAuthType, password);

    final StringBuilder debugMsg = new StringBuilder();
    debugMsg.append("successful ldap authentication for ").append(userIdentity);
    debugMsg.append(" (").append(TimeDuration.fromCurrent(startTime).asCompactString()).append(")");
    debugMsg.append(" type: ").append(returnAuthType).append(", using strategy ").append(strategy);
    debugMsg.append(", using proxy connection: ").append(useProxy);
    debugMsg
        .append(", returning bind dn: ")
        .append(
            returnProvider == null
                ? "none"
                : returnProvider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN));
    log(PwmLogLevel.INFO, debugMsg);
    pwmApplication
        .getAuditManager()
        .submit(
            pwmApplication
                .getAuditManager()
                .createUserAuditRecord(
                    AuditEvent.AUTHENTICATE,
                    this.userIdentity,
                    makeAuditLogMessage(returnAuthType),
                    sessionLabel.getSrcAddress(),
                    sessionLabel.getSrcHostname()));

    return authenticationResult;
  }