/** * */ package org.ovirt.engine.core.utils.kerberos; import static org.ovirt.engine.core.utils.kerberos.InstallerConstants.ERROR_PREFIX; import java.sql.Connection; import java.sql.Driver; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Map; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.core.engineencryptutils.EncryptionUtils; import org.ovirt.engine.core.utils.CLIParser; /** * */ public class KerberosUpgrade { public enum Arguments { user, password, connection_string, jaas_file, krb5_conf_path, mixed_mode; } public enum OptionNames { AdUserName, AdUserPassword, DomainName, CertAlias, keystorePass, keystoreUrl; } public KerberosUpgrade() { } public static void main(String[] args) { KerberosUpgrade util = new KerberosUpgrade(); CLIParser parser = new CLIParser(args); if (!util.validate(parser)) { System.exit(1); } String krb5ConfPath = parser.getArg(Arguments.krb5_conf_path.name()); try { util.registerJDBCDriver(); } catch (Exception e) { handleError(e, "Error in registering JDBC driver"); } Connection connection = null; try { connection = util.openConnection(parser); } catch (Exception e) { handleError(e, "Error in connecting to oVirt database"); } Map<String, String> results = null; String adUserName = null; String adPassword = null; String adDomainName = null; try { // Get relevant records from vdc_options results = util.getOptions(connection); // Get all relevant values from the records, decrypt username and password of AD user if possible adUserName = results.get(OptionNames.AdUserName.name()); adPassword = results.get(OptionNames.AdUserPassword.name()); adDomainName = results.get(OptionNames.DomainName.name()); String certAlias = results.get(OptionNames.CertAlias.name()); String keystoreUrl = results.get(OptionNames.keystoreUrl.name()); String keystorePass = results.get(OptionNames.keystorePass.name()); adPassword = decryptADPassword(adPassword, certAlias, keystoreUrl, keystorePass); // Create the krb5 conf file util.runKrb5ConfCreator(parser, krb5ConfPath, adDomainName); } catch (SQLException e) { handleError(e, "Error in querying oVirt database for Active-Directory user, password and domains"); } KerberosConfigCheck configCheck = new KerberosConfigCheck(); StringBuffer userGuid = new StringBuffer(); // Check authentication and user information retrieval try { configCheck.checkInstallation(adDomainName, adUserName, adPassword, parser.getArg(Arguments.jaas_file.name()), krb5ConfPath, userGuid); } catch (Exception e) { System.err.println(ERROR_PREFIX + e.getMessage()); System.exit(1); } } private static String decryptADPassword( String adPassword, String certAlias, String keystoreUrl, String keystorePass) { try { return EncryptionUtils.decrypt(adPassword, keystoreUrl, keystorePass, certAlias); } catch (Exception e) { System.err.println("Failed to decrypt AD password"); return adPassword; } } public void runKrb5ConfCreator(CLIParser parser, String krb5ConfPath, String adDomainName) { KrbConfCreator confCreator = null; StringBuffer buffer = null; try { confCreator = new KrbConfCreator(adDomainName); } catch (Exception ex) { handleError(ex, "Error in loading kerberos configuration template file"); } try { buffer = confCreator.parse(parser.getArg(Arguments.mixed_mode.name())); } catch (AuthenticationException authException) { handleError(authException, "Error in creating kerberos configuration file"); } try { confCreator.toFile(krb5ConfPath, buffer); } catch (Exception ex) { handleError(ex, "Error in writing kerberos configuration file"); } } private Map<String, String> getOptions(Connection connection) throws SQLException { Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet rs = statement.executeQuery("select option_name,option_value from vdc_options where option_name " + getOptionsSQLClause()); Map<String, String> results = new HashMap<String, String>(); rs.first(); while (!rs.isAfterLast()) { for (OptionNames optionName : OptionNames.values()) { String optionNameFromDB = rs.getString("option_name"); String optionValueFromDB = rs.getString("option_value"); if (optionNameFromDB.equals(optionName.name()) && optionValueFromDB != null) { results.put(optionName.name(), optionValueFromDB); break; } } rs.next(); } return results; } private String getOptionsSQLClause() { StringBuilder sb = new StringBuilder(); OptionNames[] enumValues = OptionNames.values(); sb.append(" in ('"); sb.append(StringHelper.join("','", enumValues)); sb.append("')"); System.out.println(sb.toString()); return sb.toString(); } private static void handleError(Exception e, String string) { e.printStackTrace(); System.out.println(InstallerConstants.ERROR_PREFIX + e.getMessage()); if (e instanceof AuthenticationException) { System.exit(((AuthenticationException) e).getAuthResult().getExitCode()); } System.exit(1); } private Connection openConnection(CLIParser parser) throws SQLException { String connString = parser.getArg(Arguments.connection_string.toString()); String dbUserName = parser.getArg(Arguments.user.toString()); String password = parser.getArg(Arguments.password.toString()); return java.sql.DriverManager.getConnection(connString, dbUserName, password); } private void registerJDBCDriver() throws Exception { Driver d = (Driver) Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance(); } private boolean validate(CLIParser parser) { for (Arguments arg : Arguments.values()) { if (!parser.hasArg(arg.name())) { System.out.println(arg.name() + " is required"); return false; } } return true; } }