// --- BEGIN COPYRIGHT BLOCK --- // 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; version 2 of the License. // // 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., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.csadmin; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.Enumeration; import java.util.Random; import java.util.StringTokenizer; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPAttributeSet; import netscape.ldap.LDAPConnection; import netscape.ldap.LDAPDN; import netscape.ldap.LDAPEntry; import netscape.ldap.LDAPException; import netscape.ldap.LDAPModification; import netscape.ldap.LDAPSearchConstraints; import netscape.ldap.LDAPSearchResults; import netscape.ldap.LDAPv3; import org.apache.velocity.context.Context; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.IAuthSubsystem; import com.netscape.certsrv.authorization.IAuthzSubsystem; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.IDBSubsystem; import com.netscape.certsrv.property.Descriptor; import com.netscape.certsrv.property.IDescriptor; import com.netscape.certsrv.property.PropertySet; import com.netscape.certsrv.usrgrp.IUGSubsystem; import com.netscape.certsrv.util.HttpInput; import com.netscape.cms.servlet.wizard.WizardServlet; import com.netscape.cmsutil.ldap.LDAPUtil; public class DatabasePanel extends WizardPanelBase { private static final String HOST = "localhost"; private static final String CLONE_HOST="Enter FQDN here"; private static final String PORT = "389"; private static final String BASEDN = "o=netscapeCertificateServer"; private static final String BINDDN = "cn=Directory Manager"; private static final String DATABASE = "csRoot"; private static final String MASTER_AGREEMENT = "masteragreement-"; private static final String CLONE_AGREEMENT = "cloneagreement-"; private WizardServlet mServlet = null; public DatabasePanel() {} /** * Initializes this panel. */ public void init(ServletConfig config, int panelno) throws ServletException { setPanelNo(panelno); setName("Internal Database"); } public void init(WizardServlet servlet, ServletConfig config, int panelno, String id) throws ServletException { setPanelNo(panelno); setName("Internal Database"); setId(id); mServlet = servlet; } public void cleanUp() throws IOException { IConfigStore cs = CMS.getConfigStore(); cs.putBoolean("preop.Database.done", false); } public boolean isPanelDone() { IConfigStore cs = CMS.getConfigStore(); try { boolean s = cs.getBoolean("preop.Database.done", false); if (s != true) { return false; } else { return true; } } catch (EBaseException e) {} return false; } public PropertySet getUsage() { PropertySet set = new PropertySet(); Descriptor hostDesc = new Descriptor(IDescriptor.STRING, null, null, "Host name"); set.add("hostname", hostDesc); Descriptor portDesc = new Descriptor(IDescriptor.INTEGER, null, null, "Port"); set.add("portStr", portDesc); Descriptor basednDesc = new Descriptor(IDescriptor.STRING, null, null, "Base DN"); set.add("basedn", basednDesc); Descriptor binddnDesc = new Descriptor(IDescriptor.STRING, null, null, "Bind DN"); set.add("binddn", binddnDesc); Descriptor bindpwdDesc = new Descriptor(IDescriptor.PASSWORD, null, null, "Bind Password"); set.add("bindpwd", bindpwdDesc); Descriptor databaseDesc = new Descriptor(IDescriptor.STRING, null, null, "Database"); set.add("database", databaseDesc); return set; } /** * Display the panel. */ public void display(HttpServletRequest request, HttpServletResponse response, Context context) { CMS.debug("DatabasePanel: display()"); context.put("title", "Internal Database"); context.put("firsttime", "false"); IConfigStore cs = CMS.getConfigStore(); String hostname = null; String portStr = null; String basedn = null; String binddn = null; String bindpwd = ""; String database = null; String errorString = ""; String secure = "false"; String cloneStartTLS = "false"; try { String s = cs.getString("preop.database.removeData"); } catch (Exception e) { context.put("firsttime", "true"); } String select = ""; try { select = cs.getString("preop.subsystem.select", ""); } catch (Exception e) { } if (isPanelDone()) { try { hostname = cs.getString("internaldb.ldapconn.host", ""); portStr = cs.getString("internaldb.ldapconn.port", ""); basedn = cs.getString("internaldb.basedn", ""); binddn = cs.getString("internaldb.ldapauth.bindDN", ""); database = cs.getString("internaldb.database", ""); secure = cs.getString("internaldb.ldapconn.secureConn", ""); cloneStartTLS = cs.getString("internaldb.ldapconn.cloneStartTLS", ""); errorString = cs.getString("preop.database.errorString", ""); } catch (Exception e) { CMS.debug("DatabasePanel display: " + e.toString()); } } else if (select.equals("clone")) { hostname = CLONE_HOST; portStr = PORT; try { basedn = cs.getString("internaldb.basedn", ""); } catch (Exception e) { CMS.debug( "DatabasePanel::display() - " + "Exception="+e.toString() ); return; } binddn = BINDDN; database = basedn.substring(basedn.lastIndexOf('=')+1); CMS.debug("Clone: database=" + database); } else { hostname = HOST; portStr = PORT; String instanceId = ""; String machineName = ""; try { instanceId = cs.getString("instanceId", ""); machineName = cs.getString("machineName", ""); } catch (Exception e) { CMS.debug("DatabasePanel display: " + e.toString()); } String suffix = "dc=" + machineName + "-" + instanceId; boolean multipleEnable = false; try { multipleEnable = cs.getBoolean( "internaldb.multipleSuffix.enable", false); } catch (Exception e) { } if (multipleEnable) basedn = "ou=" + instanceId + "," + suffix; else basedn = suffix; binddn = BINDDN; database = machineName + "-" + instanceId; } context.put("clone", select); context.put("hostname", hostname); context.put("portStr", portStr); context.put("basedn", basedn); context.put("binddn", binddn); context.put("bindpwd", bindpwd); context.put("database", database); context.put("secureConn", (secure.equals("true")? "on":"off")); context.put("cloneStartTLS", (cloneStartTLS.equals("true")? "on":"off")); context.put("panel", "admin/console/config/databasepanel.vm"); context.put("errorString", errorString); } public void initParams(HttpServletRequest request, Context context) throws IOException { IConfigStore config = CMS.getConfigStore(); String select = ""; try { select = config.getString("preop.subsystem.select", ""); } catch (Exception e) { } context.put("clone", select); context.put("hostname", request.getParameter("host")); context.put("portStr", request.getParameter("port")); context.put("basedn", request.getParameter("basedn")); context.put("binddn", request.getParameter("binddn")); context.put("bindpwd", request.getParameter("__bindpwd")); context.put("database", request.getParameter("database")); } /** * Checks if the given parameters are valid. */ public void validate(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException { IConfigStore cs = CMS.getConfigStore(); context.put("firsttime", "false"); try { String s = cs.getString("preop.database.removeData"); } catch (Exception e) { context.put("firsttime", "true"); } String hostname = HttpInput.getHostname(request, "host"); context.put("hostname", hostname); String portStr = HttpInput.getPortNumber(request, "port"); context.put("portStr", portStr); String basedn = HttpInput.getDN(request, "basedn"); context.put("basedn", basedn); String binddn = HttpInput.getDN(request, "binddn"); context.put("binddn", binddn); String database = HttpInput.getLdapDatabase(request, "database"); context.put("database", database); String bindpwd = HttpInput.getPassword(request, "__bindpwd"); context.put("bindpwd", bindpwd); String secure = HttpInput.getCheckbox(request, "secureConn"); context.put("secureConn", secure); String cloneStartTLS = HttpInput.getCheckbox(request, "cloneStartTLS"); context.put("cloneStartTLS", cloneStartTLS); String select = ""; try { select = cs.getString("preop.subsystem.select", ""); } catch (Exception e) { } if (select.equals("clone")) { String masterhost = ""; String masterport = ""; String masterbasedn = ""; try { masterhost = cs.getString("preop.internaldb.master.hostname", ""); masterport = cs.getString("preop.internaldb.master.port", ""); masterbasedn = cs.getString("preop.internaldb.master.basedn", ""); } catch (Exception e) { } //get the real host name String realhostname = ""; if (hostname.equals("localhost")) { try { realhostname = cs.getString("machineName", ""); } catch (Exception ee) { } } if (masterhost.equals(realhostname) && masterport.equals(portStr)) { context.put("updateStatus", "validate-failure"); throw new IOException("Master and clone must not share the same internal database"); } if (!masterbasedn.equals(basedn)) { context.put("updateStatus", "validate-failure"); throw new IOException("Master and clone should have the same base DN"); } } if (hostname == null || hostname.length() == 0) { cs.putString("preop.database.errorString", "Host is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Host is empty string"); } if (portStr != null && portStr.length() > 0) { int port = -1; try { port = Integer.parseInt(portStr); } catch (Exception e) { cs.putString("preop.database.errorString", "Port is invalid"); context.put("updateStatus", "validate-failure"); throw new IOException("Port is invalid"); } } else { cs.putString("preop.database.errorString", "Port is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Port is empty string"); } if (basedn == null || basedn.length() == 0) { cs.putString("preop.database.errorString", "Base DN is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Base DN is empty string"); } if (binddn == null || binddn.length() == 0) { cs.putString("preop.database.errorString", "Bind DN is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Bind DN is empty string"); } if (database == null || database.length() == 0) { cs.putString("preop.database.errorString", "Database is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Database is empty string"); } if (bindpwd == null || bindpwd.length() == 0) { cs.putString("preop.database.errorString", "Bind password is empty string"); context.put("updateStatus", "validate-failure"); throw new IOException("Bind password is empty string"); } context.put("errorString", ""); cs.putString("preop.database.errorString", ""); } private LDAPConnection getLocalLDAPConn(Context context, String secure) throws IOException { IConfigStore cs = CMS.getConfigStore(); String host = ""; String port = ""; String pwd = ""; String binddn = ""; String security = ""; try { host = cs.getString("internaldb.ldapconn.host"); port = cs.getString("internaldb.ldapconn.port"); binddn = cs.getString("internaldb.ldapauth.bindDN"); pwd = (String) context.get("bindpwd"); security = cs.getString("internaldb.ldapconn.secureConn"); } catch (Exception e) { CMS.debug("DatabasePanel populateDB: " + e.toString()); throw new IOException( "Failed to retrieve LDAP information from CS.cfg."); } int p = -1; try { p = Integer.parseInt(port); } catch (Exception e) { CMS.debug("DatabasePanel populateDB: " + e.toString()); throw new IOException("Port is not valid"); } LDAPConnection conn = null; if (security.equals("true")) { CMS.debug("DatabasePanel populateDB: creating secure (SSL) connection for internal ldap"); conn = new LDAPConnection(CMS.getLdapJssSSLSocketFactory()); } else { CMS.debug("DatabasePanel populateDB: creating non-secure (non-SSL) connection for internal ldap"); conn = new LDAPConnection(); } CMS.debug("DatabasePanel connecting to " + host + ":" + p); try { conn.connect(host, p, binddn, pwd); } catch (LDAPException e) { CMS.debug("DatabasePanel populateDB: " + e.toString()); throw new IOException("Failed to connect to the internal database."); } return conn; } private boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i=0; i