public void init(final Configuration config) throws PwmException { final Map<FileValue.FileInformation, FileValue.FileContent> fileValue = config.readSettingAsFile(PwmSetting.DATABASE_JDBC_DRIVER); final byte[] jdbcDriverBytes; if (fileValue != null && !fileValue.isEmpty()) { final FileValue.FileInformation fileInformation1 = fileValue.keySet().iterator().next(); final FileValue.FileContent fileContent = fileValue.get(fileInformation1); jdbcDriverBytes = fileContent.getContents(); } else { jdbcDriverBytes = null; } this.dbConfiguration = new DBConfiguration( config.readSettingAsString(PwmSetting.DATABASE_CLASS), config.readSettingAsString(PwmSetting.DATABASE_URL), config.readSettingAsString(PwmSetting.DATABASE_USERNAME), config.readSettingAsPassword(PwmSetting.DATABASE_PASSWORD), config.readSettingAsString(PwmSetting.DATABASE_COLUMN_TYPE_KEY), config.readSettingAsString(PwmSetting.DATABASE_COLUMN_TYPE_VALUE), jdbcDriverBytes); this.instanceID = pwmApplication == null ? null : pwmApplication.getInstanceID(); this.traceLogging = config.readSettingAsBoolean(PwmSetting.DATABASE_DEBUG_TRACE); if (this.dbConfiguration.isEmpty()) { status = PwmService.STATUS.CLOSED; LOGGER.debug("skipping database connection open, no connection parameters configured"); } }
private void restUpdateLdapForm( final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean) throws IOException, PwmUnrecoverableException { final StoredConfigurationImpl storedConfiguration = configGuideBean.getStoredConfiguration(); final Map<String, String> incomingFormData = pwmRequest.readBodyAsJsonStringMap(); if (incomingFormData != null) { configGuideBean.getFormData().putAll(incomingFormData); } if (incomingFormData != null && incomingFormData.get(PARAM_TEMPLATE_NAME) != null && !incomingFormData.get(PARAM_TEMPLATE_NAME).isEmpty()) { try { final PwmSettingTemplate template = PwmSettingTemplate.valueOf(incomingFormData.get(PARAM_TEMPLATE_NAME)); if (configGuideBean.getSelectedTemplate() != template) { LOGGER.debug( pwmRequest, "resetting form defaults using " + template.toString() + " template"); final Map<String, String> defaultForm = defaultForm(template); configGuideBean.getFormData().putAll(defaultForm); configGuideBean.setSelectedTemplate(template); storedConfiguration.setTemplate(template); } } catch (Exception e) { LOGGER.error("unknown template set request: " + e.getMessage()); } } final RestResultBean restResultBean = new RestResultBean(); pwmRequest.outputJsonResult(restResultBean); convertFormToConfiguration( storedConfiguration, configGuideBean.getFormData(), incomingFormData); // LOGGER.info("config: " + storedConfiguration.toString()); }
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)); }
private static String getLdapUrlFromFormConfig(final Map<String, String> ldapForm) { final String ldapServerIP = ldapForm.get(PARAM_LDAP_HOST); final String ldapServerPort = ldapForm.get(PARAM_LDAP_PORT); final boolean ldapServerSecure = "true".equalsIgnoreCase(ldapForm.get(PARAM_LDAP_SECURE)); return "ldap" + (ldapServerSecure ? "s" : "") + "://" + ldapServerIP + ":" + ldapServerPort; }
public static void convertFormToConfiguration( final StoredConfigurationImpl storedConfiguration, final Map<String, String> ldapForm, final Map<String, String> incomingLdapForm) throws PwmUnrecoverableException { { final String newLdapURI = getLdapUrlFromFormConfig(ldapForm); final StringArrayValue newValue = new StringArrayValue(Collections.singletonList(newLdapURI)); storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_URLS, LDAP_PROFILE_KEY, newValue, null); } { // proxy/admin account final String ldapAdminDN = ldapForm.get(PARAM_LDAP_PROXY_DN); final String ldapAdminPW = ldapForm.get(PARAM_LDAP_PROXY_PW); storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE_KEY, new StringValue(ldapAdminDN), null); final PasswordValue passwordValue = new PasswordValue(PasswordData.forStringValue(ldapAdminPW)); storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE_KEY, passwordValue, null); } storedConfiguration.writeSetting( PwmSetting.LDAP_CONTEXTLESS_ROOT, LDAP_PROFILE_KEY, new StringArrayValue(Collections.singletonList(ldapForm.get(PARAM_LDAP_CONTEXT))), null); { final String ldapContext = ldapForm.get(PARAM_LDAP_CONTEXT); storedConfiguration.writeSetting( PwmSetting.LDAP_CONTEXTLESS_ROOT, LDAP_PROFILE_KEY, new StringArrayValue(Collections.singletonList(ldapContext)), null); } { final String ldapTestUserDN = ldapForm.get(PARAM_LDAP_TEST_USER); storedConfiguration.writeSetting( PwmSetting.LDAP_TEST_USER_DN, LDAP_PROFILE_KEY, new StringValue(ldapTestUserDN), null); } { // set admin query final String groupDN = ldapForm.get(PARAM_LDAP_ADMIN_GROUP); final List<UserPermission> userPermissions = Collections.singletonList( new UserPermission(UserPermission.Type.ldapGroup, null, null, groupDN)); storedConfiguration.writeSetting( PwmSetting.QUERY_MATCH_PWM_ADMIN, new UserPermissionValue(userPermissions), null); } // set context based on ldap dn if (incomingLdapForm.containsKey(PARAM_APP_SITEURL)) { ldapForm.put(PARAM_APP_SITEURL, incomingLdapForm.get(PARAM_APP_SITEURL)); } storedConfiguration.writeSetting( PwmSetting.PWM_SITE_URL, new StringValue(ldapForm.get(PARAM_APP_SITEURL)), null); }
@Override public boolean contains(final DatabaseTable table, final String key) throws DatabaseException { final boolean result = get(table, key) != null; if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("result", result); LOGGER.trace( "contains operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(true, false); return result; }
private void checkLdapServer(ConfigGuideBean configGuideBean) throws PwmOperationalException, IOException { final Map<String, String> formData = configGuideBean.getFormData(); final String host = formData.get(PARAM_LDAP_HOST); final int port = Integer.parseInt(formData.get(PARAM_LDAP_PORT)); if (Boolean.parseBoolean(formData.get(PARAM_LDAP_SECURE))) { X509Utils.readRemoteCertificates(host, port); } else { InetAddress addr = InetAddress.getByName(host); SocketAddress sockaddr = new InetSocketAddress(addr, port); Socket sock = new Socket(); // this method will block for the defined number of milliseconds int timeout = 2000; sock.connect(sockaddr, timeout); } }
private void checkLdapServer(ConfigGuideBean configGuideBean) throws PwmOperationalException, IOException { final Map<String, String> formData = configGuideBean.getFormData(); final String host = formData.get(PARAM_LDAP_HOST); final int port = Integer.parseInt(formData.get(PARAM_LDAP_PORT)); { // socket test final InetAddress inetAddress = InetAddress.getByName(host); final SocketAddress socketAddress = new InetSocketAddress(inetAddress, port); final Socket socket = new Socket(); final int timeout = 2000; socket.connect(socketAddress, timeout); } if (Boolean.parseBoolean(formData.get(PARAM_LDAP_SECURE))) { X509Utils.readRemoteCertificates(host, port); } }
private void restUpdateLdapForm( final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean) throws IOException, PwmUnrecoverableException { final StoredConfiguration storedConfiguration = configGuideBean.getStoredConfiguration(); final Map<String, String> incomingFormData = pwmRequest.readBodyAsJsonStringMap(); if (incomingFormData != null) { configGuideBean.getFormData().putAll(incomingFormData); } if (incomingFormData != null && incomingFormData.get(PARAM_TEMPLATE_NAME) != null && !incomingFormData.get(PARAM_TEMPLATE_NAME).isEmpty()) { try { final PwmSettingTemplate template = PwmSettingTemplate.valueOf(incomingFormData.get(PARAM_TEMPLATE_NAME)); if (configGuideBean.getSelectedTemplate() != template) { LOGGER.debug( pwmRequest, "resetting form defaults using " + template.toString() + " template"); final Map<String, String> defaultForm = defaultForm(template); configGuideBean.getFormData().putAll(defaultForm); configGuideBean.setSelectedTemplate(template); storedConfiguration.setTemplate(template); { final String settingValue = AppProperty.LDAP_PROMISCUOUS_ENABLE.getKey() + "=true"; storedConfiguration.writeSetting( PwmSetting.APP_PROPERTY_OVERRIDES, new StringArrayValue(Collections.singletonList(settingValue)), null); } } } catch (Exception e) { LOGGER.error("unknown template set request: " + e.getMessage()); } } final RestResultBean restResultBean = new RestResultBean(); pwmRequest.outputJsonResult(restResultBean); convertFormToConfiguration( storedConfiguration, configGuideBean.getFormData(), incomingFormData); // LOGGER.info("config: " + storedConfiguration.toString()); }
@Override public boolean remove(final DatabaseTable table, final String key) throws DatabaseException { if (traceLogging) { LOGGER.trace("attempting remove operation for table=" + table + ", key=" + key); } boolean result = contains(table, key); if (result) { final StringBuilder sqlText = new StringBuilder(); sqlText.append("DELETE FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + "=?"); PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText.toString()); statement.setString(1, key); statement.executeUpdate(); LOGGER.trace("remove operation succeeded for table=" + table + ", key=" + key); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "remove operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } } if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("result", result); LOGGER.trace( "remove operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(true, false); return result; }
private static Map<PwmAboutProperty, String> getConnectionDebugProperties( final Connection connection) { if (connection != null) { try { final Map<PwmAboutProperty, String> returnObj = new LinkedHashMap<>(); final DatabaseMetaData databaseMetaData = connection.getMetaData(); returnObj.put(PwmAboutProperty.database_driverName, databaseMetaData.getDriverName()); returnObj.put(PwmAboutProperty.database_driverVersion, databaseMetaData.getDriverVersion()); returnObj.put( PwmAboutProperty.database_databaseProductName, databaseMetaData.getDatabaseProductName()); returnObj.put( PwmAboutProperty.database_databaseProductVersion, databaseMetaData.getDatabaseProductVersion()); return Collections.unmodifiableMap(returnObj); } catch (SQLException e) { LOGGER.error("error rading jdbc meta data: " + e.getMessage()); } } return Collections.emptyMap(); }
public static SchemaOperationResult extendSchema( ConfigGuideBean configGuideBean, final boolean doSchemaExtension) { final Map<String, String> form = configGuideBean.getFormData(); final boolean ldapServerSecure = "true".equalsIgnoreCase(form.get(PARAM_LDAP_SECURE)); final String ldapUrl = "ldap" + (ldapServerSecure ? "s" : "") + "://" + form.get(PARAM_LDAP_HOST) + ":" + form.get(PARAM_LDAP_PORT); try { final ChaiConfiguration chaiConfiguration = new ChaiConfiguration( ldapUrl, form.get(PARAM_LDAP_PROXY_DN), form.get(PARAM_LDAP_PROXY_PW)); chaiConfiguration.setSetting(ChaiSetting.PROMISCUOUS_SSL, "true"); final ChaiProvider chaiProvider = ChaiProviderFactory.createProvider(chaiConfiguration); if (doSchemaExtension) { return SchemaManager.extendSchema(chaiProvider); } else { return SchemaManager.checkExistingSchema(chaiProvider); } } catch (Exception e) { LOGGER.error("unable to create schema extender object: " + e.getMessage()); return null; } }
public static Map<String, Date> readIndividualReplicaLastPasswordTimes( final PwmApplication pwmApplication, final SessionLabel sessionLabel, final UserIdentity userIdentity) throws PwmUnrecoverableException { final Map<String, Date> returnValue = new LinkedHashMap<>(); final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final Collection<ChaiConfiguration> perReplicaConfigs = ChaiUtility.splitConfigurationPerReplica( chaiProvider.getChaiConfiguration(), Collections.singletonMap(ChaiSetting.FAILOVER_CONNECT_RETRIES, "1")); for (final ChaiConfiguration loopConfiguration : perReplicaConfigs) { final String loopReplicaUrl = loopConfiguration.getSetting(ChaiSetting.BIND_DN); ChaiProvider loopProvider = null; try { loopProvider = ChaiProviderFactory.createProvider(loopConfiguration); final Date lastModifiedDate = determinePwdLastModified(pwmApplication, sessionLabel, userIdentity); returnValue.put(loopReplicaUrl, lastModifiedDate); } catch (ChaiUnavailableException e) { LOGGER.error(sessionLabel, "unreachable server during replica password sync check"); e.printStackTrace(); } finally { if (loopProvider != null) { try { loopProvider.close(); } catch (Exception e) { final String errorMsg = "error closing loopProvider to " + loopReplicaUrl + " while checking individual password sync status"; LOGGER.error(sessionLabel, errorMsg); } } } } return returnValue; }
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(); }
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; }
@Override public boolean put(final DatabaseTable table, final String key, final String value) throws DatabaseException { preOperationCheck(); if (traceLogging) { LOGGER.trace("attempting put operation for table=" + table + ", key=" + key); } if (!contains(table, key)) { final String sqlText = "INSERT INTO " + table.toString() + "(" + KEY_COLUMN + ", " + VALUE_COLUMN + ") VALUES(?,?)"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText); statement.setString(1, key); statement.setString(2, value); statement.executeUpdate(); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } return false; } final String sqlText = "UPDATE " + table.toString() + " SET " + VALUE_COLUMN + "=? WHERE " + KEY_COLUMN + "=?"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sqlText); statement.setString(1, value); statement.setString(2, key); statement.executeUpdate(); } catch (SQLException e) { final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage()); lastError = errorInformation; throw new DatabaseException(errorInformation); } finally { close(statement); } if (traceLogging) { final Map<String, Object> debugOutput = new LinkedHashMap<>(); debugOutput.put("table", table); debugOutput.put("key", key); debugOutput.put("value", value); LOGGER.trace( "put operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint)); } updateStats(false, true); return true; }
public static Map<String, String> placeholderForm(PwmSettingTemplate template) { final Map<String, String> defaultLdapForm = new HashMap<>(); try { final String defaultLdapUrlString = PwmSetting.LDAP_SERVER_URLS.getPlaceholder(template); final URI uri = new URI(defaultLdapUrlString); defaultLdapForm.put(PARAM_LDAP_HOST, uri.getHost()); defaultLdapForm.put(PARAM_LDAP_PORT, String.valueOf(uri.getPort())); defaultLdapForm.put( PARAM_LDAP_SECURE, "ldaps".equalsIgnoreCase(uri.getScheme()) ? "true" : "false"); defaultLdapForm.put( PARAM_LDAP_PROXY_DN, PwmSetting.LDAP_PROXY_USER_DN.getPlaceholder(template)); defaultLdapForm.put(PARAM_LDAP_PROXY_PW, ""); defaultLdapForm.put( PARAM_LDAP_CONTEXT, PwmSetting.LDAP_CONTEXTLESS_ROOT.getPlaceholder(template)); defaultLdapForm.put( PARAM_LDAP_TEST_USER, PwmSetting.LDAP_TEST_USER_DN.getPlaceholder(template)); defaultLdapForm.put( PARAM_LDAP_ADMIN_GROUP, PwmSetting.LDAP_TEST_USER_DN.getPlaceholder(template)); defaultLdapForm.put( PARAM_CR_STORAGE_PREF, (String) PwmSetting.FORGOTTEN_PASSWORD_WRITE_PREFERENCE .getDefaultValue(template) .toNativeObject()); defaultLdapForm.put(PARAM_CONFIG_PASSWORD, ""); defaultLdapForm.put(PARAM_CONFIG_PASSWORD_VERIFY, ""); } catch (Exception e) { LOGGER.error( "error building static form values using default configuration: " + e.getMessage()); e.printStackTrace(); } return Collections.unmodifiableMap(defaultLdapForm); }
public static Map<String, String> defaultForm(PwmSettingTemplate template) { final Map<String, String> defaultLdapForm = new HashMap<>(); try { final String defaultLdapUrlString = ((List<String>) PwmSetting.LDAP_SERVER_URLS.getDefaultValue(template).toNativeObject()) .get(0); final URI uri = new URI(defaultLdapUrlString); defaultLdapForm.put(PARAM_LDAP_HOST, uri.getHost()); defaultLdapForm.put(PARAM_LDAP_PORT, String.valueOf(uri.getPort())); defaultLdapForm.put( PARAM_LDAP_SECURE, "ldaps".equalsIgnoreCase(uri.getScheme()) ? "true" : "false"); defaultLdapForm.put( PARAM_LDAP_ADMIN_DN, (String) PwmSetting.LDAP_PROXY_USER_DN.getDefaultValue(template).toNativeObject()); defaultLdapForm.put(PARAM_LDAP_ADMIN_PW, ""); defaultLdapForm.put( PARAM_LDAP_CONTEXT, ((List<String>) PwmSetting.LDAP_CONTEXTLESS_ROOT.getDefaultValue(template).toNativeObject()) .get(0)); defaultLdapForm.put( PARAM_LDAP_TEST_USER, (String) PwmSetting.LDAP_TEST_USER_DN.getDefaultValue(template).toNativeObject()); { List<UserPermission> userPermissions = (List<UserPermission>) PwmSetting.QUERY_MATCH_PWM_ADMIN.getDefaultValue(template).toNativeObject(); final String groupDN = userPermissions != null && userPermissions.size() > 0 ? userPermissions.get(0).getLdapBase() : ""; defaultLdapForm.put(PARAM_LDAP_ADMIN_GROUP, groupDN); } defaultLdapForm.put( PARAM_CR_STORAGE_PREF, (String) PwmSetting.FORGOTTEN_PASSWORD_WRITE_PREFERENCE .getDefaultValue(template) .toNativeObject()); defaultLdapForm.put(PARAM_CONFIG_PASSWORD, ""); defaultLdapForm.put(PARAM_CONFIG_PASSWORD_VERIFY, ""); } catch (Exception e) { LOGGER.error( "error building static form values using default configuration: " + e.getMessage()); e.printStackTrace(); } return Collections.unmodifiableMap(defaultLdapForm); }