Java tutorial
/* * Adito * * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.adito.activedirectory; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.adito.boot.ContextHolder; import com.adito.boot.PropertyList; import com.adito.properties.Property; import com.adito.properties.impl.realms.RealmKey; import com.adito.realms.Realm; final class ActiveDirectoryPropertyManager { private static final Log log = LogFactory.getLog(ActiveDirectoryPropertyManager.class); private static final String TEMPLATE_FILE = "krb5.template"; private static final String CONF_DIRECTORY = "activedirectory"; private static final String CONF_FILE = "krb5.conf"; private static final String PORT_SEPARATOR = ":"; private static final String START_REPLACEMENT = "${"; private static final String END_REPLACEMENT = "}"; private static final String DOMAIN = "DOMAIN"; private static final String KDC_TIMEOUT = "KDC_TIMEOUT"; private static final String KDC_MAX_TRIES = "KDC_MAX_RETRIES"; private static final String HOST_REALMS = "HOST_REALMS"; private static final String HOST_NAME = "HOST_NAME"; private static final String HOST_REALM_REPLACEMENT = "kdc = " + START_REPLACEMENT + HOST_NAME + END_REPLACEMENT; private static final String DOMAIN_REALMS = "DOMAIN_REALMS"; private static final String DOMAIN_REALM_REPLACEMENT = "." + START_REPLACEMENT + HOST_NAME + END_REPLACEMENT + " = " + START_REPLACEMENT + DOMAIN + END_REPLACEMENT; private final Properties propertyNames; private final Realm realm; ActiveDirectoryPropertyManager(Realm realm, Properties propertyNames) { this.propertyNames = propertyNames; this.realm = realm; System.setProperty("java.security.krb5.conf", getConfFile()); } private static String getConfFile() { File tempDirectory = ContextHolder.getContext().getTempDirectory(); File configurationFile = new File(tempDirectory, CONF_FILE); return configurationFile.getAbsolutePath(); } void refresh() { refresh(Collections.<String, String>emptyMap()); } void refresh(Map<String, String> alternativeValues) { try { doFileReplacement(alternativeValues); } catch (IOException e) { log.error("Failed to update Active Directory configuration " + CONF_FILE, e); } } private void doFileReplacement(Map<String, String> alternativeValues) throws IOException { File confDirectory = ContextHolder.getContext().getConfDirectory(); File templateFile = new File(confDirectory, CONF_DIRECTORY + getFileSeparator() + TEMPLATE_FILE); String readFile = readFile(templateFile); File tempDirectory = ContextHolder.getContext().getTempDirectory(); File configurationFile = new File(tempDirectory, CONF_FILE); if (!configurationFile.exists() && !configurationFile.createNewFile()) { log.error("Failed to create file " + CONF_FILE + "."); } else { String replacement = getReplacement(readFile, alternativeValues); writeFile(configurationFile, replacement); } } private String getReplacement(String fileContents, Map<String, String> alternativeValues) { Map<String, String> replacements = buildReplacements(alternativeValues); for (Map.Entry<String, String> entry : replacements.entrySet()) { fileContents = replaceValue(fileContents, entry.getKey(), entry.getValue()); } return fileContents; } private Map<String, String> buildReplacements(Map<String, String> alternativeValues) { Map<String, String> replacements = new HashMap<String, String>(); String dbDomain = Property.getProperty(getRealmKey("activeDirectory.domain")).toUpperCase().trim(); String domain = getRealValue(alternativeValues, DOMAIN, dbDomain); replacements.put(DOMAIN, domain); String dbControllerHost = Property.getProperty(getRealmKey("activeDirectory.controllerHost")); String controllerHost = getRealValue(alternativeValues, "activeDirectory.controllerHost", dbControllerHost); String dbTimeout = String .valueOf(Property.getPropertyInt(getRealmKey("activeDirectory.kdcTimeout")) * 1000); String timeout = getRealValue(alternativeValues, "activeDirectory.kdcTimeout", dbTimeout); replacements.put(KDC_TIMEOUT, timeout); String dbMaxTries = String.valueOf(Property.getPropertyInt(getRealmKey("activeDirectory.kdcMaxTries"))); String maxTries = getRealValue(alternativeValues, "activeDirectory.kdcMaxTries", dbMaxTries); replacements.put(KDC_MAX_TRIES, maxTries); PropertyList dbActiveDirectryUris = new PropertyList(); dbActiveDirectryUris.add(controllerHost); dbActiveDirectryUris.addAll(Property.getPropertyList(getRealmKey("activeDirectory.backupControllerHosts"))); PropertyList activeDirectryUris = getRealValue(alternativeValues, "activeDirectory.backupControllerHosts", dbActiveDirectryUris); replacements.put(HOST_REALMS, buildBackupHostRealms(activeDirectryUris)); replacements.put(DOMAIN_REALMS, buildBackupDomainRealms(domain, activeDirectryUris)); return replacements; } private static String getRealValue(Map<String, String> alternativeValues, String key, String value) { return alternativeValues.containsKey(key) ? alternativeValues.get(key) : value; } private static PropertyList getRealValue(Map<String, String> alternativeValues, String key, PropertyList values) { return alternativeValues.containsKey(key) ? new PropertyList(alternativeValues.get(key)) : values; } private static String replaceValue(String contents, String key, String value) { key = START_REPLACEMENT + key + END_REPLACEMENT; return contents.replace(key, value); } private static String buildBackupHostRealms(PropertyList activeDirectryUris) { StringBuffer buffer = new StringBuffer(); for (String uri : activeDirectryUris) { uri = uri.contains(PORT_SEPARATOR) ? uri.substring(0, uri.lastIndexOf(PORT_SEPARATOR)) : uri; String replace = replaceValue(HOST_REALM_REPLACEMENT, HOST_NAME, uri); buffer.append(replace).append(getLineSeparator()); } return buffer.toString(); } private static String buildBackupDomainRealms(String domain, PropertyList activeDirectryUris) { StringBuffer buffer = new StringBuffer(); for (String uri : activeDirectryUris) { uri = uri.contains(PORT_SEPARATOR) ? uri.substring(0, uri.lastIndexOf(PORT_SEPARATOR)) : uri; String replace = replaceValue(DOMAIN_REALM_REPLACEMENT, HOST_NAME, uri); replace = replaceValue(replace, DOMAIN, domain); buffer.append(replace).append(getLineSeparator()); } return buffer.toString(); } private RealmKey getRealmKey(String key) { String propertyOrDefault = propertyNames.getProperty(key, key); return new RealmKey(propertyOrDefault, realm); } private static void writeFile(File file, String contents) throws IOException { BufferedWriter output = null; try { output = new BufferedWriter(new FileWriter(file)); output.write(contents); } finally { close(output); } } private static void close(BufferedWriter writer) { try { if (writer != null) { writer.close(); } } catch (IOException e) { // ignore } } private static String readFile(File file) throws IOException { StringBuffer contents = new StringBuffer(); BufferedReader input = null; try { input = new BufferedReader(new FileReader(file)); String line = null; while ((line = input.readLine()) != null) { contents.append(line); contents.append(getLineSeparator()); } } finally { close(input); } return contents.toString(); } private static String getFileSeparator() { return System.getProperty("file.separator"); } private static String getLineSeparator() { return System.getProperty("line.separator"); } private static void close(BufferedReader reader) { try { if (reader != null) { reader.close(); } } catch (IOException e) { // ignore } } }