diff options
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java')
-rw-r--r-- | base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java | 1591 |
1 files changed, 1591 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java new file mode 100644 index 000000000..82c45d1cd --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java @@ -0,0 +1,1591 @@ +// --- 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.ArrayList; +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.ldap.ILdapConnFactory; +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 BINDDN = "cn=Directory Manager"; + + 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 masterReplicationPort = ""; + String cloneReplicationPort = ""; + String replicationSecurity = ""; + + try { + @SuppressWarnings("unused") + String s = cs.getString("preop.database.removeData"); // check whether it's first time + } 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", ""); + replicationSecurity = cs.getString("internaldb.ldapconn.replicationSecurity", "None"); + masterReplicationPort = cs.getString("internaldb.ldapconn.masterReplicationPort", ""); + cloneReplicationPort = cs.getString("internaldb.ldapconn.cloneReplicationPort", ""); + 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("masterReplicationPort", masterReplicationPort); + context.put("cloneReplicationPort", cloneReplicationPort); + context.put("replicationSecurity", replicationSecurity); + 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") != null) ? request.getParameter("host") : ""); + context.put("portStr", (request.getParameter("port") != null) ? request.getParameter("port") : ""); + context.put("basedn", (request.getParameter("basedn") != null) ? request.getParameter("basedn") : ""); + context.put("binddn", (request.getParameter("binddn") != null) ? request.getParameter("binddn") : ""); + context.put("bindpwd", (request.getParameter("__bindpwd") != null) ? + request.getParameter("__bindpwd"): ""); + context.put("database", (request.getParameter("database") != null) ? + request.getParameter("database") : ""); + context.put("masterReplicationPort", (request.getParameter("masterReplicationPort") != null) ? + request.getParameter("masterReplicationPort"): ""); + context.put("cloneReplicationPort", (request.getParameter("cloneReplicationPort") != null) ? + request.getParameter("cloneReplicationPort"): ""); + context.put("replicationSecurity", (request.getParameter("replicationSecurity") != null) ? + request.getParameter("replicationSecurity"): "None"); + } + + /** + * Parses and validates the parameters in the request. + */ + public void parseParameters(HttpServletRequest request, + HttpServletResponse response, Context context) throws IOException { + IConfigStore cs = CMS.getConfigStore(); + + String select = ""; + try { + select = cs.getString("preop.subsystem.select", ""); + } catch (Exception e) { + } + + String hostname = HttpInput.getHostname(request, "host"); + if (hostname == null || hostname.length() == 0) { + throw new IOException("hostname is empty string"); + } + context.put("hostname", hostname); + + // this validates that port is an integer + String portStr = HttpInput.getPortNumber(request, "port"); + context.put("portStr", portStr); + + String basedn = HttpInput.getDN(request, "basedn"); + if (basedn == null || basedn.length() == 0) { + throw new IOException("basedn is empty string"); + } + context.put("basedn", basedn); + + String binddn = HttpInput.getDN(request, "binddn"); + if (binddn == null || binddn.length() == 0) { + throw new IOException("binddn is empty string"); + } + context.put("binddn", binddn); + + String database = HttpInput.getLdapDatabase(request, "database"); + if (database == null || database.length() == 0) { + throw new IOException("Database is empty string"); + } + context.put("database", database); + + String bindpwd = HttpInput.getPassword(request, "__bindpwd"); + if (bindpwd == null || bindpwd.length() == 0) { + throw new IOException("Bind password is empty string"); + } + context.put("bindpwd", bindpwd); + + String secure = HttpInput.getCheckbox(request, "secureConn"); + context.put("secureConn", secure); + + String masterReplicationPort = HttpInput.getString(request, "masterReplicationPort"); + if (masterReplicationPort != null && masterReplicationPort.length() > 0) { + try { + Integer.parseInt(masterReplicationPort); // check for errors + } catch (NumberFormatException e) { + throw new IOException("Master replication port is invalid"); + } + } + context.put("masterReplicationPort", masterReplicationPort); + + String cloneReplicationPort = HttpInput.getString(request, "cloneReplicationPort"); + if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) { + try { + Integer.parseInt(cloneReplicationPort); // check for errors + } catch (Exception e) { + throw new IOException("Clone replication port is invalid"); + } + } + context.put("cloneReplicationPort", cloneReplicationPort); + + String replicationSecurity = HttpInput.getString(request, "replicationSecurity"); + context.put("replicationSecurity", replicationSecurity); + + if (select.equals("clone")) { + String masterhost = ""; + String masterport = ""; + String masterbasedn = ""; + String realhostname = ""; + try { + masterhost = cs.getString("preop.internaldb.master.ldapconn.host", ""); + masterport = cs.getString("preop.internaldb.master.ldapconn.port", ""); + masterbasedn = cs.getString("preop.internaldb.master.basedn", ""); + realhostname = cs.getString("machineName", ""); + } catch (Exception e) { + } + + if (masterhost.equals(realhostname) && masterport.equals(portStr)) { + throw new IOException("Master and clone must not share the same internal database"); + } + + if (!masterbasedn.equals(basedn)) { + throw new IOException("Master and clone should have the same base DN"); + } + } + + context.put("errorString", ""); + cs.putString("preop.database.errorString", ""); + } + + /** + * 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 { + @SuppressWarnings("unused") + String s = cs.getString("preop.database.removeData"); // check whether it's first time + } catch (Exception e) { + context.put("firsttime", "true"); + } + + try { + parseParameters(request, response, context); + } catch (IOException e) { + context.put("errorString", e.getMessage()); + cs.putString("preop.database.errorString", e.getMessage()); + context.put("updateStatus", "validate-failure"); + throw e; + } + + 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 < children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + return false; + } + } + } + + // The directory is now empty so delete it + return dir.delete(); + } + + private void cleanupDB(LDAPConnection conn, String baseDN, String database) { + String[] entries = {}; + String filter = "objectclass=*"; + LDAPSearchConstraints cons = null; + String[] attrs = null; + String dn = ""; + try { + CMS.debug("Deleting baseDN: " + baseDN); + LDAPSearchResults res = conn.search(baseDN, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res != null) + deleteEntries(res, conn, baseDN, entries); + } catch (LDAPException e) { + } + + try { + dn = "cn=mapping tree, cn=config"; + filter = "nsslapd-backend=" + database; + LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_ONE, filter, + attrs, true, cons); + if (res != null) { + while (res.hasMoreElements()) { + dn = res.next().getDN(); + filter = "objectclass=*"; + LDAPSearchResults res2 = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res2 != null) + deleteEntries(res2, conn, dn, entries); + } + } + } catch (LDAPException e) { + } + + try { + dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res != null) { + deleteEntries(res, conn, dn, entries); + String dbdir = getInstanceDir(conn) + "/db/" + database; + if (dbdir != null) { + CMS.debug(" Deleting dbdir " + dbdir); + boolean success = deleteDir(new File(dbdir)); + if (!success) { + CMS.debug("Unable to delete database directory " + dbdir); + } + } + } + } catch (LDAPException e) { + } + } + + private void populateDB(HttpServletRequest request, Context context, String secure) + throws IOException { + IConfigStore cs = CMS.getConfigStore(); + + String baseDN = ""; + String database = ""; + String dn = ""; + + try { + baseDN = cs.getString("internaldb.basedn"); + database = cs.getString("internaldb.database", ""); + } catch (Exception e) { + CMS.debug("DatabasePanel populateDB: " + e.toString()); + throw new IOException( + "Failed to retrieve LDAP information from CS.cfg."); + } + + String remove = HttpInput.getID(request, "removeData"); + LDAPConnection conn = getLocalLDAPConn(context, secure); + + // check that the database and baseDN do not exist + + boolean foundBaseDN = false; + boolean foundDatabase = false; + try { + LDAPEntry entry = conn.read(baseDN); + if (entry != null) + foundBaseDN = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + CMS.debug("DatabasePanel update: LDAPException " + e.toString()); + throw new IOException("Failed to create the database"); + } + } + + try { + dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPEntry entry = conn.read(dn); + if (entry != null) + foundDatabase = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + CMS.debug("DatabasePanel update: LDAPException " + e.toString()); + throw new IOException("Failed to create the database"); + } + } + try { + dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config"; + LDAPEntry entry = conn.read(dn); + if (entry != null) + foundDatabase = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + CMS.debug("DatabasePanel update: LDAPException " + e.toString()); + throw new IOException("Failed to create the database"); + } + } + + if (foundDatabase) { + CMS.debug("DatabasePanel update: This database has already been used."); + if (remove == null) { + throw new IOException( + "This database has already been used. Select the checkbox below to remove all data and reuse this database"); + } else { + CMS.debug("DatabasePanel update: Deleting existing DB and reusing base DN"); + cleanupDB(conn, baseDN, database); + foundBaseDN = false; + foundDatabase = false; + } + } + + if (foundBaseDN) { + CMS.debug("DatabasePanel update: This base DN has already been used."); + if (remove == null) { + throw new IOException( + "This base DN (" + + baseDN + + ") has already been used. Select the checkbox below to remove all data and reuse this base DN"); + } else { + CMS.debug("DatabasePanel update: Deleting existing DB and reusing base DN"); + cleanupDB(conn, baseDN, database); + foundBaseDN = false; + foundDatabase = false; + } + } + + // create database + try { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc[] = { "top", "extensibleObject", "nsBackendInstance" }; + attrs.add(new LDAPAttribute("objectClass", oc)); + attrs.add(new LDAPAttribute("cn", database)); + attrs.add(new LDAPAttribute("nsslapd-suffix", baseDN)); + dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPEntry entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("Warning: database creation error - " + e.toString()); + throw new IOException("Failed to create the database."); + } + + try { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc2[] = { "top", "extensibleObject", "nsMappingTree" }; + attrs.add(new LDAPAttribute("objectClass", oc2)); + attrs.add(new LDAPAttribute("cn", baseDN)); + attrs.add(new LDAPAttribute("nsslapd-backend", database)); + attrs.add(new LDAPAttribute("nsslapd-state", "Backend")); + dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config"; + LDAPEntry entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("Warning: database mapping tree creation error - " + e.toString()); + throw new IOException("Failed to create the database."); + } + + try { + // create base dn + CMS.debug("Creating base DN: " + baseDN); + String dns3[] = LDAPDN.explodeDN(baseDN, false); + StringTokenizer st = new StringTokenizer(dns3[0], "="); + String n = st.nextToken(); + String v = st.nextToken(); + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc3[] = { "top", "domain" }; + if (n.equals("o")) { + oc3[1] = "organization"; + } else if (n.equals("ou")) { + oc3[1] = "organizationalUnit"; + } + attrs.add(new LDAPAttribute("objectClass", oc3)); + attrs.add(new LDAPAttribute(n, v)); + + LDAPEntry entry = new LDAPEntry(baseDN, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("Warning: suffix creation error - " + e.toString()); + throw new IOException("Failed to create the base DN: " + baseDN); + } + + // check to see if the base dn exists + CMS.debug("DatabasePanel checking existing " + baseDN); + + try { + LDAPEntry entry = conn.read(baseDN); + + if (entry != null) { + foundBaseDN = true; + } + } catch (LDAPException e) { + } + boolean createBaseDN = true; + + boolean testing = false; + try { + testing = cs.getBoolean("internaldb.multipleSuffix.enable", false); + } catch (Exception e) { + } + + if (!foundBaseDN) { + if (!testing) { + context.put("errorString", + "Base DN was not found. Please make sure to create the suffix in the internal database."); + throw new IOException("Base DN not found"); + } + + if (createBaseDN) { + // only auto create if it is an ou entry + String dns1[] = LDAPDN.explodeDN(baseDN, false); + + if (dns1 == null) { + throw new IOException("Invalid base DN"); + } + if (!dns1[0].startsWith("ou")) { + throw new IOException( + "Failed to find base DN, and failed to create non ou entry."); + } + String dns2[] = LDAPDN.explodeDN(baseDN, true); + // support only one level creation - create new entry + // right under the suffix + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc[] = { "top", "organizationalUnit" }; + + attrs.add(new LDAPAttribute("objectClass", oc)); + attrs.add(new LDAPAttribute("ou", dns2[0])); + LDAPEntry entry = new LDAPEntry(baseDN, attrs); + + try { + conn.add(entry); + foundBaseDN = true; + CMS.debug("DatabasePanel added " + baseDN); + } catch (LDAPException e) { + throw new IOException("Failed to create " + baseDN); + } + } + } + if (!foundBaseDN) { + throw new IOException("Failed to find base DN"); + } + + String select = ""; + try { + select = cs.getString("preop.subsystem.select", ""); + } catch (Exception e) { + } + + if (select.equals("clone")) { + // if this is clone, add index before replication + // don't put in the schema or bad things will happen + importLDIFS("preop.internaldb.ldif", conn); + importLDIFS("preop.internaldb.index_ldif", conn); + importLDIFS("preop.internaldb.manager_ldif", conn); + } else { + // data will be replicated from the master to the clone + // so clone does not need the data + importLDIFS("preop.internaldb.schema.ldif", conn); + importLDIFS("preop.internaldb.ldif", conn); + importLDIFS("preop.internaldb.data_ldif", conn); + importLDIFS("preop.internaldb.index_ldif", conn); + importLDIFS("preop.internaldb.manager_ldif", conn); + } + + try { + conn.disconnect(); + } catch (LDAPException e) { + } + } + + private void importLDIFS(String param, LDAPConnection conn) throws IOException { + IConfigStore cs = CMS.getConfigStore(); + String v = null; + + CMS.debug("DatabasePanel populateDB param=" + param); + try { + v = cs.getString(param); + } catch (EBaseException e) { + CMS.debug("DatabasePanel populateDB: " + e.toString()); + throw new IOException("Cant find ldif files."); + } + + StringTokenizer tokenizer = new StringTokenizer(v, ","); + String baseDN = null; + String database = null; + + try { + baseDN = cs.getString("internaldb.basedn"); + } catch (EBaseException e) { + throw new IOException("internaldb.basedn is missing."); + } + + try { + database = cs.getString("internaldb.database"); + CMS.debug("DatabasePanel update: database=" + database); + } catch (EBaseException e) { + CMS.debug( + "DatabasePanel update: Failed to get database name. Exception: " + + e.toString()); + database = "userRoot"; + } + + String instancePath = null; + + try { + instancePath = cs.getString("instanceRoot"); + } catch (EBaseException e) { + throw new IOException("instanceRoot is missing"); + } + + String instanceId = null; + + try { + instanceId = cs.getString("instanceId"); + } catch (EBaseException e) { + throw new IOException("instanceId is missing"); + } + + String dbuser = null; + try { + dbuser = "uid=" + cs.getString("cs.type") + "-" + cs.getString("machineName") + "-" + + cs.getString("service.securePort") + ",ou=people," + baseDN; + } catch (EBaseException e) { + CMS.debug("Unable to construct dbuser" + e.toString()); + e.printStackTrace(); + throw new IOException("unable to construct dbuser"); + } + + String configDir = instancePath + File.separator + "conf"; + + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken().trim(); + int index = token.lastIndexOf("/"); + String name = token; + + if (index != -1) { + name = token.substring(index + 1); + } + + CMS.debug("DatabasePanel importLDIFS: ldif file = " + token); + String filename = configDir + File.separator + name; + + CMS.debug("DatabasePanel importLDIFS: ldif file copy to " + filename); + PrintStream ps = null; + BufferedReader in = null; + + try { + in = new BufferedReader(new FileReader(token)); + ps = new PrintStream(new FileOutputStream(filename, false)); + while (in.ready()) { + String s = in.readLine(); + int n = s.indexOf("{"); + + if (n == -1) { + ps.println(s); + } else { + boolean endOfline = false; + + while (n != -1) { + ps.print(s.substring(0, n)); + int n1 = s.indexOf("}"); + String tok = s.substring(n + 1, n1); + + if (tok.equals("instanceId")) { + ps.print(instanceId); + } else if (tok.equals("rootSuffix")) { + ps.print(baseDN); + } else if (tok.equals("database")) { + ps.print(database); + } else if (tok.equals("dbuser")) { + ps.print(dbuser); + } + if ((s.length() + 1) == n1) { + endOfline = true; + break; + } + s = s.substring(n1 + 1); + n = s.indexOf("{"); + } + + if (!endOfline) { + ps.println(s); + } + } + } + in.close(); + ps.close(); + } catch (Exception e) { + CMS.debug("DBSubsystem popuateDB: " + e.toString()); + throw new IOException( + "Problem of copying ldif file: " + filename); + } + ArrayList<String> errors = new ArrayList<String>(); + LDAPUtil.importLDIF(conn, filename, errors); + if (! errors.isEmpty()) { + CMS.debug("DatabasePanel: importLDIFS: LDAP Errors in importing " + filename); + for (String error: errors) { + CMS.debug(error); + } + } + } + } + + + /** + * Commit parameter changes + */ + public void update(HttpServletRequest request, + HttpServletResponse response, + Context context) throws IOException { + IConfigStore cs = CMS.getConfigStore(); + boolean hasErr = false; + + context.put("firsttime", "false"); + try { + @SuppressWarnings("unused") + String s = cs.getString("preop.database.removeData"); // check whether it's first time + } catch (Exception e) { + context.put("firsttime", "true"); + } + + String hostname1 = ""; + String portStr1 = ""; + String database1 = ""; + String masterPortStr = ""; + + try { + hostname1 = cs.getString("internaldb.ldapconn.host", ""); + portStr1 = cs.getString("internaldb.ldapconn.port", ""); + database1 = cs.getString("internaldb.database", ""); + masterPortStr = cs.getString("preop.internaldb.master.ldapconn.port", "0"); + } catch (Exception e) { + } + + try { + parseParameters(request, response, context); + } catch (IOException e) { + context.put("errorString", e.getMessage()); + cs.putString("preop.database.errorString", e.getMessage()); + context.put("updateStatus", "validate-failure"); + throw e; + } + + String hostname2 = (String) context.get("hostname"); + String portStr2 = (String) context.get("portStr"); + String database2 = (String) context.get("database"); + String basedn2 = (String) context.get("basedn"); + String binddn = (String) context.get("binddn"); + String secure = (String) context.get("secureConn"); + String masterReplicationPortStr = (String) context.get("masterReplicationPort"); + String cloneReplicationPortStr = (String) context.get("cloneReplicationPort"); + + cs.putString("internaldb.ldapconn.host", hostname2); + cs.putString("internaldb.ldapconn.port", portStr2); + cs.putString("internaldb.database", database2); + cs.putString("internaldb.basedn", basedn2); + cs.putString("internaldb.ldapauth.bindDN", binddn); + cs.putString("internaldb.ldapconn.secureConn", (secure.equals("on") ? "true" : "false")); + + int masterReplicationPort = 0; + if ((masterReplicationPortStr == null) || (masterReplicationPortStr.length() == 0)) { + masterReplicationPortStr = masterPortStr; + } + masterReplicationPort = Integer.parseInt(masterReplicationPortStr); + cs.putString("internaldb.ldapconn.masterReplicationPort", masterReplicationPortStr); + + int cloneReplicationPort = 0; + int port = Integer.parseInt(portStr2); + if ((cloneReplicationPortStr == null) || (cloneReplicationPortStr.length() == 0)) { + cloneReplicationPortStr = portStr2; + } + cloneReplicationPort = Integer.parseInt(cloneReplicationPortStr); + cs.putString("internaldb.ldapconn.cloneReplicationPort", cloneReplicationPortStr); + + String replicationSecurity = HttpInput.getString(request, "replicationSecurity"); + if ((cloneReplicationPort == port) && (secure.equals("true"))) { + replicationSecurity = "SSL"; + } else if (replicationSecurity == null) { + replicationSecurity = "None"; + } + cs.putString("internaldb.ldapconn.replicationSecurity", replicationSecurity); + + String remove = HttpInput.getID(request, "removeData"); + if (isPanelDone() && (remove == null || remove.equals(""))) { + /* if user submits the same data, they just want to skip + to the next panel, no database population is required. */ + if (hostname1.equals(hostname2) && + portStr1.equals(portStr2) && + database1.equals(database2)) { + context.put("updateStatus", "success"); + return; + } + } + + mServlet.cleanUpFromPanel(mServlet.getPanelNo(request)); + + try { + populateDB(request, context, (secure.equals("on") ? "true" : "false")); + } catch (IOException e) { + CMS.debug("DatabasePanel update: populateDB Exception: " + e.toString()); + context.put("updateStatus", "failure"); + throw e; + } catch (Exception e) { + CMS.debug("DatabasePanel update: populateDB Exception: " + e.toString()); + context.put("errorString", e.toString()); + cs.putString("preop.database.errorString", e.toString()); + context.put("updateStatus", "failure"); + throw new IOException(e.toString()); + } + + String bindpwd = HttpInput.getPassword(request, "__bindpwd"); + + /* BZ 430745 create password for replication manager */ + String replicationpwd = Integer.toString(new Random().nextInt()); + + IConfigStore psStore = null; + String passwordFile = null; + + try { + passwordFile = cs.getString("passwordFile"); + psStore = CMS.createFileConfigStore(passwordFile); + } catch (Exception e) { + CMS.debug("ConfigDatabaseServlet update: " + e.toString()); + context.put("updateStatus", "failure"); + throw new IOException(e.toString()); + } + psStore.putString("internaldb", bindpwd); + psStore.putString("replicationdb", replicationpwd); + cs.putString("preop.internaldb.replicationpwd", replicationpwd); + cs.putString("preop.database.removeData", "false"); + + try { + cs.commit(false); + psStore.commit(false); + CMS.reinit(IDBSubsystem.SUB_ID); + String type = cs.getString("cs.type", ""); + if (type.equals("CA")) + CMS.reinit(ICertificateAuthority.ID); + CMS.reinit(IAuthSubsystem.ID); + CMS.reinit(IAuthzSubsystem.ID); + CMS.reinit(IUGSubsystem.ID); + } catch (Exception e) { + CMS.debug("DatabasePanel update: " + e.toString()); + context.put("errorString", e.toString()); + cs.putString("preop.database.errorString", e.toString()); + context.put("updateStatus", "failure"); + throw new IOException(e.toString()); + } + + String select = ""; + try { + select = cs.getString("preop.subsystem.select", ""); + } catch (Exception e) { + } + + // always populate the index the last + try { + CMS.debug("Populating local indexes"); + LDAPConnection conn = getLocalLDAPConn(context, + (secure.equals("on") ? "true" : "false")); + importLDIFS("preop.internaldb.post_ldif", conn); + + /* For vlvtask, we need to check if the task has + been completed or not. Presence of nsTaskExitCode means task is complete + */ + String wait_dn = cs.getString("preop.internaldb.wait_dn", ""); + if (!wait_dn.equals("")) { + int i = 0; + LDAPEntry task = null; + boolean taskComplete = false; + CMS.debug("Checking wait_dn " + wait_dn); + do { + Thread.sleep(1000); + try { + task = conn.read(wait_dn, (String[]) null); + if (task != null) { + LDAPAttribute attr = task.getAttribute("nsTaskExitCode"); + if (attr != null) { + taskComplete = true; + String val = (String) attr.getStringValues().nextElement(); + if (val.compareTo("0") != 0) { + CMS.debug("Error in populating local indexes: nsTaskExitCode=" + val); + } + } + } + } catch (LDAPException le) { + CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")"); + } catch (Exception e) { + CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + e.toString() + ")."); + } + } while ((!taskComplete) && (i < 20)); + if (i < 20) { + CMS.debug("Done checking wait_dn " + wait_dn); + } else { + CMS.debug("Done checking wait_dn " + wait_dn + " due to timeout."); + } + } + + conn.disconnect(); + CMS.debug("Done populating local indexes"); + } catch (Exception e) { + CMS.debug("Populating index failure - " + e); + } + + // setup replication after indexes have been created + if (select.equals("clone")) { + CMS.debug("Start setting up replication."); + setupReplication(request, context, (secure.equals("on") ? "true" : "false"), + replicationSecurity, masterReplicationPort, cloneReplicationPort); + CMS.debug("Finish setting up replication."); + + try { + CMS.reinit(IDBSubsystem.SUB_ID); + String type = cs.getString("cs.type", ""); + if (type.equals("CA")) + CMS.reinit(ICertificateAuthority.ID); + CMS.reinit(IAuthSubsystem.ID); + CMS.reinit(IAuthzSubsystem.ID); + CMS.reinit(IUGSubsystem.ID); + } catch (Exception e) { + } + } + + if (hasErr == false) { + cs.putBoolean("preop.Database.done", true); + try { + cs.commit(false); + } catch (EBaseException e) { + CMS.debug( + "DatabasePanel: update() Exception caught at config commit: " + + e.toString()); + } + } + context.put("updateStatus", "success"); + } + + private void setupReplication(HttpServletRequest request, + Context context, String secure, String replicationSecurity, + int masterReplicationPort, int cloneReplicationPort) + throws IOException { + IConfigStore cs = CMS.getConfigStore(); + + String cstype = ""; + String machinename = ""; + String instanceId = ""; + try { + cstype = cs.getString("cs.type"); + cstype = toLowerCaseSubsystemType(cstype); + machinename = cs.getString("machineName", ""); + instanceId = cs.getString("instanceId", ""); + } catch (Exception e) { + } + + //setup replication agreement + String masterAgreementName = "masterAgreement1-" + machinename + "-" + instanceId; + cs.putString("internaldb.replication.master", masterAgreementName); + String cloneAgreementName = "cloneAgreement1-" + machinename + "-" + instanceId; + cs.putString("internaldb.replication.consumer", cloneAgreementName); + + try { + cs.commit(false); + } catch (Exception e) { + } + + // get connection to master + LDAPConnection masterConn = null; + ILdapConnFactory masterFactory = null; + try { + IConfigStore masterCfg = cs.getSubStore("preop.internaldb.master"); + masterFactory = CMS.getLdapBoundConnFactory(); + masterFactory.init(masterCfg); + masterConn = masterFactory.getConn(); + } catch (Exception e) { + CMS.debug("Failed to set up connection to master:" + e.toString()); + e.printStackTrace(); + throw new IOException("Failed to set up replication: No connection to master"); + } + + // get connection to replica + LDAPConnection replicaConn = null; + ILdapConnFactory replicaFactory = null; + try { + IConfigStore replicaCfg = cs.getSubStore("internaldb"); + replicaFactory = CMS.getLdapBoundConnFactory(); + replicaFactory.init(replicaCfg); + replicaConn = replicaFactory.getConn(); + } catch (Exception e) { + CMS.debug("Failed to set up connection to replica:" + e.toString()); + e.printStackTrace(); + throw new IOException("Failed to set up replication: No connection to replica"); + } + + String master_hostname = ""; + String master_replicationpwd = ""; + String replica_hostname = ""; + String replica_replicationpwd = ""; + + try { + master_hostname = cs.getString("preop.internaldb.master.ldapconn.host", ""); + master_replicationpwd = cs.getString("preop.internaldb.master.replication.password", ""); + replica_hostname = cs.getString("internaldb.ldapconn.host", ""); + replica_replicationpwd = cs.getString("preop.internaldb.replicationpwd", ""); + } catch (Exception e) { + } + + String basedn = ""; + try { + basedn = cs.getString("internaldb.basedn"); + } catch (Exception e) { + } + + try { + String suffix = cs.getString("internaldb.basedn", ""); + + String replicadn = "cn=replica,cn=\"" + suffix + "\",cn=mapping tree,cn=config"; + CMS.debug("DatabasePanel setupReplication: replicadn=" + replicadn); + + String masterBindUser = "Replication Manager " + masterAgreementName; + String cloneBindUser = "Replication Manager " + cloneAgreementName; + + createReplicationManager(masterConn, masterBindUser, master_replicationpwd); + createReplicationManager(replicaConn, cloneBindUser, replica_replicationpwd); + + String dir1 = getInstanceDir(masterConn); + createChangeLog(masterConn, dir1 + "/changelogs"); + + String dir2 = getInstanceDir(replicaConn); + createChangeLog(replicaConn, dir2 + "/changelogs"); + + int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1); + + replicaId = enableReplication(replicadn, masterConn, masterBindUser, basedn, replicaId); + replicaId = enableReplication(replicadn, replicaConn, cloneBindUser, basedn, replicaId); + cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId)); + + CMS.debug("DatabasePanel setupReplication: Finished enabling replication"); + + createReplicationAgreement(replicadn, masterConn, masterAgreementName, + replica_hostname, cloneReplicationPort, replica_replicationpwd, basedn, + cloneBindUser, secure, replicationSecurity); + + createReplicationAgreement(replicadn, replicaConn, cloneAgreementName, + master_hostname, masterReplicationPort, master_replicationpwd, basedn, + masterBindUser, secure, replicationSecurity); + + // initialize consumer + initializeConsumer(replicadn, masterConn, masterAgreementName); + + while (!replicationDone(replicadn, masterConn, masterAgreementName)) { + CMS.debug("DatabasePanel setupReplication: Waiting for replication to complete"); + Thread.sleep(1000); + } + + String status = replicationStatus(replicadn, masterConn, masterAgreementName); + if (!status.startsWith("0 ")) { + CMS.debug("DatabasePanel setupReplication: consumer initialization failed. " + + status); + throw new IOException("consumer initialization failed. " + status); + } + + // remove master ldap password from password.conf (if present) + String passwordFile = cs.getString("passwordFile"); + IConfigStore psStore = CMS.createFileConfigStore(passwordFile); + psStore.remove("master_internaldb"); + psStore.commit(false); + + } catch (Exception e) { + CMS.debug("DatabasePanel setupReplication: " + e.toString()); + throw new IOException("Failed to setup the replication for cloning."); + } + } + + /** + * If validiate() returns false, this method will be called. + */ + public void displayError(HttpServletRequest request, + HttpServletResponse response, + Context context) { + + try { + initParams(request, context); + } catch (IOException e) { + } + context.put("title", "Database"); + context.put("panel", "admin/console/config/databasepanel.vm"); + } + + private void createReplicationManager(LDAPConnection conn, String bindUser, String pwd) + throws LDAPException { + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + String dn = "cn=" + bindUser + ",ou=csusers,cn=config"; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "person")); + attrs.add(new LDAPAttribute("userpassword", pwd)); + attrs.add(new LDAPAttribute("cn", bindUser)); + attrs.add(new LDAPAttribute("sn", "manager")); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("DatabasePanel createReplicationManager: Replication Manager has already used"); + try { + conn.delete(dn); + conn.add(entry); + } catch (LDAPException ee) { + CMS.debug("DatabasePanel createReplicationManager: " + ee.toString()); + } + return; + } else { + CMS.debug("DatabasePanel createReplicationManager: Failed to create replication manager. Exception: " + + e.toString()); + throw e; + } + } + + CMS.debug("DatabasePanel createReplicationManager: Successfully created Replication Manager"); + } + + private void createChangeLog(LDAPConnection conn, String dir) + throws LDAPException { + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + String dn = "cn=changelog5,cn=config"; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "extensibleObject")); + attrs.add(new LDAPAttribute("cn", "changelog5")); + attrs.add(new LDAPAttribute("nsslapd-changelogdir", dir)); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("DatabasePanel createChangeLog: Changelog entry has already used"); + /* leave it, dont delete it because it will have operation error + try { + conn.delete(dn); + conn.add(entry); + } catch (LDAPException ee) { + CMS.debug("DatabasePanel createChangeLog: "+ee.toString()); + } + */ + return; + } else { + CMS.debug("DatabasePanel createChangeLog: Failed to create changelog entry. Exception: " + e.toString()); + throw e; + } + } + + CMS.debug("DatabasePanel createChangeLog: Successfully create change log entry"); + } + + private int enableReplication(String replicadn, LDAPConnection conn, String bindUser, String basedn, int id) + throws LDAPException { + CMS.debug("DatabasePanel enableReplication: replicadn: " + replicadn); + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "nsDS5Replica")); + attrs.add(new LDAPAttribute("objectclass", "extensibleobject")); + attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn)); + attrs.add(new LDAPAttribute("nsDS5ReplicaType", "3")); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", + "cn=" + bindUser + ",ou=csusers,cn=config")); + attrs.add(new LDAPAttribute("cn", "replica")); + attrs.add(new LDAPAttribute("nsDS5ReplicaId", Integer.toString(id))); + attrs.add(new LDAPAttribute("nsds5flags", "1")); + entry = new LDAPEntry(replicadn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + /* BZ 470918 -we cant just add the new dn. We need to do a replace instead + * until the DS code is fixed */ + CMS.debug("DatabasePanel enableReplication: " + replicadn + " has already been used"); + + try { + entry = conn.read(replicadn); + LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN"); + attr.addValue("cn=" + bindUser + ",ou=csusers,cn=config"); + LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr); + conn.modify(replicadn, mod); + } catch (LDAPException ee) { + CMS.debug("DatabasePanel enableReplication: Failed to modify " + + replicadn + " entry. Exception: " + e.toString()); + } + return id; + } else { + CMS.debug("DatabasePanel enableReplication: Failed to create " + + replicadn + " entry. Exception: " + e.toString()); + return id; + } + } + + CMS.debug("DatabasePanel enableReplication: Successfully create " + replicadn + " entry."); + return id + 1; + } + + private void createReplicationAgreement(String replicadn, + LDAPConnection conn, String name, String replicahost, int replicaport, + String replicapwd, String basedn, String bindUser, String secure, String replicationSecurity) + throws LDAPException { + String dn = "cn=" + name + "," + replicadn; + CMS.debug("DatabasePanel createReplicationAgreement: dn: " + dn); + LDAPEntry entry = null; + LDAPAttributeSet attrs = null; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", + "nsds5replicationagreement")); + attrs.add(new LDAPAttribute("cn", name)); + attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn)); + attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost)); + + attrs.add(new LDAPAttribute("nsDS5ReplicaPort", "" + replicaport)); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", + "cn=" + bindUser + ",ou=csusers,cn=config")); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple")); + attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd)); + + if (replicationSecurity.equals("SSL")) { + attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL")); + } else if (replicationSecurity.equals("TLS")) { + attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "TLS")); + } + + CMS.debug("About to set description attr to " + name); + attrs.add(new LDAPAttribute("description", name)); + + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("DatabasePanel createReplicationAgreement: " + dn + " has already used"); + try { + conn.delete(dn); + } catch (LDAPException ee) { + CMS.debug("DatabasePanel createReplicationAgreement: " + ee.toString()); + throw ee; + } + + try { + conn.add(entry); + } catch (LDAPException ee) { + CMS.debug("DatabasePanel createReplicationAgreement: " + ee.toString()); + throw ee; + } + } else { + CMS.debug("DatabasePanel createReplicationAgreement: Failed to create " + + dn + " entry. Exception: " + e.toString()); + throw e; + } + } + + CMS.debug("DatabasePanel createReplicationAgreement: Successfully create replication agreement " + name); + } + + private void initializeConsumer(String replicadn, LDAPConnection conn, + String name) { + String dn = "cn=" + name + "," + replicadn; + CMS.debug("DatabasePanel initializeConsumer: initializeConsumer dn: " + dn); + CMS.debug("DatabasePanel initializeConsumer: initializeConsumer host: " + + conn.getHost() + " port: " + conn.getPort()); + try { + LDAPAttribute attr = new LDAPAttribute("nsds5beginreplicarefresh", + "start"); + LDAPModification mod = new LDAPModification( + LDAPModification.REPLACE, attr); + CMS.debug("DatabasePanel initializeConsumer: start modifying"); + conn.modify(dn, mod); + CMS.debug("DatabasePanel initializeConsumer: Finish modification."); + } catch (LDAPException e) { + CMS.debug("DatabasePanel initializeConsumer: Failed to modify " + dn + " entry. Exception: " + e.toString()); + return; + } catch (Exception e) { + CMS.debug("DatabasePanel initializeConsumer: exception " + e); + } + + try { + CMS.debug("DatabasePanel initializeConsumer: thread sleeping for 5 seconds."); + Thread.sleep(5000); + CMS.debug("DatabasePanel initializeConsumer: finish sleeping."); + } catch (InterruptedException ee) { + CMS.debug("DatabasePanel initializeConsumer: exception: " + ee.toString()); + } + + CMS.debug("DatabasePanel initializeConsumer: Successfully initialize consumer"); + } + + private boolean replicationDone(String replicadn, LDAPConnection conn, String name) + throws IOException { + String dn = "cn=" + name + "," + replicadn; + String filter = "(objectclass=*)"; + String[] attrs = { "nsds5beginreplicarefresh" }; + + CMS.debug("DatabasePanel replicationDone: dn: " + dn); + try { + LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, true); + + int count = results.getCount(); + if (count < 1) { + throw new IOException("Replication entry not found"); + } + + LDAPEntry entry = results.next(); + LDAPAttribute refresh = entry.getAttribute("nsds5beginreplicarefresh"); + if (refresh == null) { + return true; + } + return false; + } catch (Exception e) { + CMS.debug("DatabasePanel replicationDone: exception " + e); + throw new IOException("Exception in replicationDone: " + e); + } + } + + private String replicationStatus(String replicadn, LDAPConnection conn, String name) + throws IOException { + String dn = "cn=" + name + "," + replicadn; + String filter = "(objectclass=*)"; + String[] attrs = { "nsds5replicalastinitstatus" }; + + CMS.debug("DatabasePanel replicationStatus: dn: " + dn); + try { + LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, false); + + int count = results.getCount(); + if (count < 1) { + throw new IOException("Replication entry not found"); + } + + LDAPEntry entry = results.next(); + LDAPAttribute attr = entry.getAttribute("nsds5replicalastinitstatus"); + if (attr != null) { + @SuppressWarnings("unchecked") + Enumeration<String> valsInAttr = attr.getStringValues(); + if (valsInAttr.hasMoreElements()) { + return valsInAttr.nextElement(); + } else { + throw new IOException("No value returned for nsds5replicalastinitstatus"); + } + } else { + throw new IOException("nsDS5ReplicaLastInitStatus is null."); + } + } catch (Exception e) { + CMS.debug("DatabasePanel replicationStatus: exception " + e); + throw new IOException("Exception in replicationStatus: " + e); + } + } + + private String getInstanceDir(LDAPConnection conn) { + String instancedir = ""; + try { + String filter = "(objectclass=*)"; + String[] attrs = { "nsslapd-directory" }; + LDAPSearchResults results = + conn.search("cn=config,cn=ldbm database,cn=plugins,cn=config", LDAPv3.SCOPE_SUB, + filter, attrs, false); + + while (results.hasMoreElements()) { + LDAPEntry entry = results.next(); + String dn = entry.getDN(); + CMS.debug("DatabasePanel getInstanceDir: DN for storing nsslapd-directory: " + dn); + LDAPAttributeSet entryAttrs = entry.getAttributeSet(); + @SuppressWarnings("unchecked") + Enumeration<LDAPAttribute> attrsInSet = entryAttrs.getAttributes(); + while (attrsInSet.hasMoreElements()) { + LDAPAttribute nextAttr = attrsInSet.nextElement(); + String attrName = nextAttr.getName(); + CMS.debug("DatabasePanel getInstanceDir: attribute name: " + attrName); + @SuppressWarnings("unchecked") + Enumeration<String> valsInAttr = nextAttr.getStringValues(); + while (valsInAttr.hasMoreElements()) { + String nextValue = valsInAttr.nextElement(); + if (attrName.equalsIgnoreCase("nsslapd-directory")) { + CMS.debug("DatabasePanel getInstanceDir: instanceDir=" + nextValue); + return nextValue.substring(0, nextValue.lastIndexOf("/db")); + } + } + } + } + } catch (LDAPException e) { + CMS.debug("DatabasePanel getInstanceDir: Error in retrieving the instance directory. Exception: " + + e.toString()); + } + + return instancedir; + } +} |