001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2011 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.util; 018 019import static org.opends.messages.AdminToolMessages.*; 020import static org.opends.server.backends.pluggable.SuffixContainer.*; 021 022import java.net.InetAddress; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.HashSet; 027import java.util.List; 028import java.util.Set; 029import java.util.SortedSet; 030import java.util.TreeSet; 031 032import org.forgerock.i18n.LocalizableMessage; 033import org.forgerock.i18n.slf4j.LocalizedLogger; 034import org.forgerock.opendj.config.server.ConfigException; 035import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 036import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 037import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; 038import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; 039import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 040import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; 041import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor; 042import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 043import org.opends.guitools.controlpanel.datamodel.VLVSortOrder; 044import org.opends.guitools.controlpanel.task.OfflineUpdateException; 045import org.opends.server.admin.server.ServerManagementContext; 046import org.opends.server.admin.std.server.AdministrationConnectorCfg; 047import org.opends.server.admin.std.server.BackendCfg; 048import org.opends.server.admin.std.server.BackendIndexCfg; 049import org.opends.server.admin.std.server.BackendVLVIndexCfg; 050import org.opends.server.admin.std.server.BackupBackendCfg; 051import org.opends.server.admin.std.server.ConnectionHandlerCfg; 052import org.opends.server.admin.std.server.HTTPConnectionHandlerCfg; 053import org.opends.server.admin.std.server.JMXConnectionHandlerCfg; 054import org.opends.server.admin.std.server.LDAPConnectionHandlerCfg; 055import org.opends.server.admin.std.server.LDIFBackendCfg; 056import org.opends.server.admin.std.server.LDIFConnectionHandlerCfg; 057import org.opends.server.admin.std.server.MemoryBackendCfg; 058import org.opends.server.admin.std.server.MonitorBackendCfg; 059import org.opends.server.admin.std.server.PluggableBackendCfg; 060import org.opends.server.admin.std.server.ReplicationDomainCfg; 061import org.opends.server.admin.std.server.ReplicationServerCfg; 062import org.opends.server.admin.std.server.ReplicationSynchronizationProviderCfg; 063import org.opends.server.admin.std.server.RootCfg; 064import org.opends.server.admin.std.server.RootDNCfg; 065import org.opends.server.admin.std.server.RootDNUserCfg; 066import org.opends.server.admin.std.server.SNMPConnectionHandlerCfg; 067import org.opends.server.admin.std.server.TaskBackendCfg; 068import org.opends.server.core.DirectoryServer; 069import org.forgerock.opendj.ldap.DN; 070import org.opends.server.types.OpenDsException; 071 072/** 073 * A class that reads the configuration information from the files. 074 */ 075public class ConfigFromFile extends ConfigReader 076{ 077 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 078 079 /** 080 * Creates a new instance of this config file handler. No initialization 081 * should be performed here, as all of that work should be done in the 082 * <CODE>initializeConfigHandler</CODE> method. 083 */ 084 public ConfigFromFile() 085 { 086 super(); 087 } 088 089 /** 090 * Reads configuration information from the configuration files. 091 */ 092 public void readConfiguration() 093 { 094 final List<OpenDsException> errors = new ArrayList<>(); 095 final Set<ConnectionHandlerDescriptor> connectionHandlers = new HashSet<>(); 096 final Set<BackendDescriptor> backendDescriptors = new HashSet<>(); 097 final Set<DN> alternateBindDNs = new HashSet<>(); 098 try 099 { 100 DirectoryServer.getInstance().initializeConfiguration(); 101 102 readSchemaIfNeeded(errors); 103 readConfig(connectionHandlers, backendDescriptors, alternateBindDNs, errors); 104 } 105 catch (final OpenDsException oe) 106 { 107 errors.add(oe); 108 } 109 catch (final Throwable t) 110 { 111 logger.warn(LocalizableMessage.raw("Error reading configuration: " + t, t)); 112 errors.add(new OfflineUpdateException(ERR_READING_CONFIG_LDAP.get(t.getMessage()), t)); 113 } 114 115 if (!errors.isEmpty() && environmentSettingException != null) 116 { 117 errors.add(0, environmentSettingException); 118 } 119 120 for (final OpenDsException oe : errors) 121 { 122 logger.warn(LocalizableMessage.raw("Error reading configuration: " + oe, oe)); 123 } 124 exceptions = Collections.unmodifiableList(errors); 125 administrativeUsers = Collections.unmodifiableSet(alternateBindDNs); 126 listeners = Collections.unmodifiableSet(connectionHandlers); 127 backends = Collections.unmodifiableSet(backendDescriptors); 128 } 129 130 private void readSchemaIfNeeded(final List<OpenDsException> errors) throws ConfigException 131 { 132 if (mustReadSchema()) 133 { 134 try 135 { 136 readSchema(); 137 if (getSchema() != null) 138 { 139 // Update the schema: so that when we call the server code the 140 // latest schema read on the server we are managing is used. 141 DirectoryServer.setSchema(getSchema()); 142 } 143 } 144 catch (final OpenDsException oe) 145 { 146 errors.add(oe); 147 } 148 } 149 } 150 151 private void readConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, 152 final Set<BackendDescriptor> backendDescriptors, final Set<DN> alternateBindDNs, 153 final List<OpenDsException> errors) throws OpenDsException, ConfigException 154 { 155 // Get the Directory Server configuration handler and use it. 156 final RootCfg root = ServerManagementContext.getInstance().getRootConfiguration(); 157 readAdminConnector(root, errors); 158 readConnectionHandlers(connectionHandlers, root, errors); 159 isSchemaEnabled = root.getGlobalConfiguration().isCheckSchema(); 160 161 readBackendConfiguration(backendDescriptors, root, errors); 162 boolean isReplicationSecure = readIfReplicationIsSecure(root, errors); 163 ReplicationSynchronizationProviderCfg sync = readSyncProviderIfExists(root); 164 if (sync != null) 165 { 166 readReplicationConfig(connectionHandlers, backendDescriptors, sync, isReplicationSecure, errors); 167 } 168 readAlternateBindDNs(alternateBindDNs, root, errors); 169 } 170 171 private void readAdminConnector(final RootCfg root, final List<OpenDsException> errors) throws OpenDsException 172 { 173 try 174 { 175 final AdministrationConnectorCfg adminConnector = root.getAdministrationConnector(); 176 this.adminConnector = getConnectionHandler(adminConnector); 177 } 178 catch (final ConfigException ce) 179 { 180 errors.add(toConfigException(ce)); 181 } 182 } 183 184 private void readConnectionHandlers(final Set<ConnectionHandlerDescriptor> connectionHandlers, final RootCfg root, 185 final List<OpenDsException> errors) throws ConfigException 186 { 187 for (final String connHandler : root.listConnectionHandlers()) 188 { 189 try 190 { 191 final ConnectionHandlerCfg connectionHandler = root.getConnectionHandler(connHandler); 192 connectionHandlers.add(getConnectionHandler(connectionHandler, connHandler)); 193 } 194 catch (final OpenDsException oe) 195 { 196 errors.add(oe); 197 } 198 } 199 } 200 201 private void readBackendConfiguration(final Set<BackendDescriptor> backendDescriptors, final RootCfg root, 202 final List<OpenDsException> errors) 203 { 204 for (final String backendName : root.listBackends()) 205 { 206 try 207 { 208 final BackendCfg backend = root.getBackend(backendName); 209 final Set<BaseDNDescriptor> baseDNs = new HashSet<>(); 210 for (final DN dn : backend.getBaseDN()) 211 { 212 final BaseDNDescriptor baseDN = 213 new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED, dn, null, -1, -1, -1); 214 baseDNs.add(baseDN); 215 } 216 final Set<IndexDescriptor> indexes = new HashSet<>(); 217 final Set<VLVIndexDescriptor> vlvIndexes = new HashSet<>(); 218 BackendDescriptor.Type type = getBackendType(backend); 219 if (type == BackendDescriptor.Type.PLUGGABLE) 220 { 221 refreshBackendConfig(indexes, vlvIndexes, backend, errors); 222 } 223 224 final BackendDescriptor desc = 225 new BackendDescriptor(backend.getBackendId(), baseDNs, indexes, vlvIndexes, -1, backend.isEnabled(), type); 226 for (final AbstractIndexDescriptor index : indexes) 227 { 228 index.setBackend(desc); 229 } 230 for (final AbstractIndexDescriptor index : vlvIndexes) 231 { 232 index.setBackend(desc); 233 } 234 235 backendDescriptors.add(desc); 236 } 237 catch (final ConfigException ce) 238 { 239 errors.add(toConfigException(ce)); 240 } 241 } 242 } 243 244 private BackendDescriptor.Type getBackendType(final BackendCfg backend) 245 { 246 if (backend instanceof PluggableBackendCfg) 247 { 248 return BackendDescriptor.Type.PLUGGABLE; 249 } 250 else if (backend instanceof LDIFBackendCfg) 251 { 252 return BackendDescriptor.Type.LDIF; 253 } 254 else if (backend instanceof MemoryBackendCfg) 255 { 256 return BackendDescriptor.Type.MEMORY; 257 } 258 else if (backend instanceof BackupBackendCfg) 259 { 260 return BackendDescriptor.Type.BACKUP; 261 } 262 else if (backend instanceof MonitorBackendCfg) 263 { 264 return BackendDescriptor.Type.MONITOR; 265 } 266 else if (backend instanceof TaskBackendCfg) 267 { 268 return BackendDescriptor.Type.TASK; 269 } 270 else 271 { 272 return BackendDescriptor.Type.OTHER; 273 } 274 } 275 276 private void refreshBackendConfig(final Set<IndexDescriptor> indexes, 277 final Set<VLVIndexDescriptor> vlvIndexes, final BackendCfg backend, final List<OpenDsException> errors) 278 { 279 final PluggableBackendCfg db = (PluggableBackendCfg) backend; 280 readBackendIndexes(indexes, errors, db); 281 readBackendVLVIndexes(vlvIndexes, errors, db); 282 } 283 284 private void readBackendIndexes(final Set<IndexDescriptor> indexes, final List<OpenDsException> errors, 285 final PluggableBackendCfg db) 286 { 287 indexes.add(new IndexDescriptor(DN2ID_INDEX_NAME)); 288 indexes.add(new IndexDescriptor(ID2CHILDREN_COUNT_NAME)); 289 try 290 { 291 for (final String indexName : db.listBackendIndexes()) 292 { 293 final BackendIndexCfg index = db.getBackendIndex(indexName); 294 indexes.add(new IndexDescriptor( 295 index.getAttribute().getNameOrOID(), index.getAttribute(), 296 null, IndexTypeDescriptor.fromBackendIndexTypes(index.getIndexType()), index.getIndexEntryLimit())); 297 } 298 } 299 catch (ConfigException ce) 300 { 301 errors.add(toConfigException(ce)); 302 } 303 } 304 305 private void readBackendVLVIndexes(final Set<VLVIndexDescriptor> vlvIndexes, 306 final List<OpenDsException> errors, final PluggableBackendCfg db) 307 { 308 try 309 { 310 for (final String vlvIndexName : db.listBackendVLVIndexes()) 311 { 312 final BackendVLVIndexCfg index = db.getBackendVLVIndex(vlvIndexName); 313 final List<VLVSortOrder> sortOrder = getVLVSortOrder(index.getSortOrder()); 314 vlvIndexes.add(new VLVIndexDescriptor( 315 index.getName(), null, index.getBaseDN(), VLVIndexDescriptor.toSearchScope(index.getScope()), 316 index.getFilter(), sortOrder)); 317 } 318 } 319 catch (ConfigException ce) 320 { 321 errors.add(toConfigException(ce)); 322 } 323 } 324 325 private boolean readIfReplicationIsSecure(final RootCfg root, final List<OpenDsException> errors) 326 { 327 try 328 { 329 return root.getCryptoManager().isSSLEncryption(); 330 } 331 catch (final ConfigException ce) 332 { 333 errors.add(toConfigException(ce)); 334 return false; 335 } 336 } 337 338 private ReplicationSynchronizationProviderCfg readSyncProviderIfExists(final RootCfg root) 339 { 340 replicationPort = -1; 341 try 342 { 343 return (ReplicationSynchronizationProviderCfg) root.getSynchronizationProvider("Multimaster Synchronization"); 344 } 345 catch (final ConfigException ce) 346 { 347 // Ignore this one 348 return null; 349 } 350 } 351 352 private void readReplicationConfig(final Set<ConnectionHandlerDescriptor> connectionHandlers, 353 final Set<BackendDescriptor> backendDescriptors, ReplicationSynchronizationProviderCfg sync, 354 boolean isReplicationSecure, final List<OpenDsException> errors) 355 { 356 try 357 { 358 if (sync.isEnabled() && sync.hasReplicationServer()) 359 { 360 final ReplicationServerCfg replicationServer = sync.getReplicationServer(); 361 if (replicationServer != null) 362 { 363 replicationPort = replicationServer.getReplicationPort(); 364 final ConnectionHandlerDescriptor.Protocol protocol = 365 isReplicationSecure ? ConnectionHandlerDescriptor.Protocol.REPLICATION_SECURE 366 : ConnectionHandlerDescriptor.Protocol.REPLICATION; 367 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 368 final ConnectionHandlerDescriptor connHandler = 369 new ConnectionHandlerDescriptor(new HashSet<InetAddress>(), replicationPort, protocol, 370 ConnectionHandlerDescriptor.State.ENABLED, "Multimaster Synchronization", emptySet); 371 connectionHandlers.add(connHandler); 372 } 373 } 374 final String[] domains = sync.listReplicationDomains(); 375 if (domains != null) 376 { 377 for (final String domain2 : domains) 378 { 379 final ReplicationDomainCfg domain = sync.getReplicationDomain(domain2); 380 final DN dn = domain.getBaseDN(); 381 for (final BackendDescriptor backend : backendDescriptors) 382 { 383 for (final BaseDNDescriptor baseDN : backend.getBaseDns()) 384 { 385 if (baseDN.getDn().equals(dn)) 386 { 387 baseDN 388 .setType(sync.isEnabled() ? BaseDNDescriptor.Type.REPLICATED : BaseDNDescriptor.Type.DISABLED); 389 baseDN.setReplicaID(domain.getServerId()); 390 } 391 } 392 } 393 } 394 } 395 } 396 catch (final ConfigException ce) 397 { 398 errors.add(toConfigException(ce)); 399 } 400 } 401 402 private void readAlternateBindDNs(final Set<DN> dns, final RootCfg root, final List<OpenDsException> errors) 403 { 404 try 405 { 406 final RootDNCfg rootDN = root.getRootDN(); 407 final String[] rootUsers = rootDN.listRootDNUsers(); 408 dns.clear(); 409 if (rootUsers != null) 410 { 411 for (final String rootUser2 : rootUsers) 412 { 413 final RootDNUserCfg rootUser = rootDN.getRootDNUser(rootUser2); 414 dns.addAll(rootUser.getAlternateBindDN()); 415 } 416 } 417 } 418 catch (final ConfigException ce) 419 { 420 errors.add(toConfigException(ce)); 421 } 422 } 423 424 private org.opends.server.config.ConfigException toConfigException(final ConfigException ce) 425 { 426 return new org.opends.server.config.ConfigException(ce.getMessageObject(), ce); 427 } 428 429 private ConnectionHandlerDescriptor getConnectionHandler(final ConnectionHandlerCfg connHandler, final String name) 430 throws OpenDsException 431 { 432 final SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 433 434 final ConnectionHandlerDescriptor.State state = 435 connHandler.isEnabled() ? ConnectionHandlerDescriptor.State.ENABLED 436 : ConnectionHandlerDescriptor.State.DISABLED; 437 438 ConnectionHandlerDescriptor.Protocol protocol; 439 int port; 440 if (connHandler instanceof LDAPConnectionHandlerCfg) 441 { 442 final LDAPConnectionHandlerCfg ldap = (LDAPConnectionHandlerCfg) connHandler; 443 if (ldap.isUseSSL()) 444 { 445 protocol = ConnectionHandlerDescriptor.Protocol.LDAPS; 446 } 447 else if (ldap.isAllowStartTLS()) 448 { 449 protocol = ConnectionHandlerDescriptor.Protocol.LDAP_STARTTLS; 450 } 451 else 452 { 453 protocol = ConnectionHandlerDescriptor.Protocol.LDAP; 454 } 455 addAll(addresses, ldap.getListenAddress()); 456 port = ldap.getListenPort(); 457 } 458 else if (connHandler instanceof HTTPConnectionHandlerCfg) 459 { 460 final HTTPConnectionHandlerCfg http = (HTTPConnectionHandlerCfg) connHandler; 461 if (http.isUseSSL()) 462 { 463 protocol = ConnectionHandlerDescriptor.Protocol.HTTPS; 464 } 465 else 466 { 467 protocol = ConnectionHandlerDescriptor.Protocol.HTTP; 468 } 469 addAll(addresses, http.getListenAddress()); 470 port = http.getListenPort(); 471 } 472 else if (connHandler instanceof JMXConnectionHandlerCfg) 473 { 474 final JMXConnectionHandlerCfg jmx = (JMXConnectionHandlerCfg) connHandler; 475 if (jmx.isUseSSL()) 476 { 477 protocol = ConnectionHandlerDescriptor.Protocol.JMXS; 478 } 479 else 480 { 481 protocol = ConnectionHandlerDescriptor.Protocol.JMX; 482 } 483 addresses.add(jmx.getListenAddress()); 484 port = jmx.getListenPort(); 485 } 486 else if (connHandler instanceof LDIFConnectionHandlerCfg) 487 { 488 protocol = ConnectionHandlerDescriptor.Protocol.LDIF; 489 port = -1; 490 } 491 else if (connHandler instanceof SNMPConnectionHandlerCfg) 492 { 493 protocol = ConnectionHandlerDescriptor.Protocol.SNMP; 494 final SNMPConnectionHandlerCfg snmp = (SNMPConnectionHandlerCfg) connHandler; 495 addAll(addresses, snmp.getListenAddress()); 496 port = snmp.getListenPort(); 497 } 498 else 499 { 500 protocol = ConnectionHandlerDescriptor.Protocol.OTHER; 501 port = -1; 502 } 503 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 504 return new ConnectionHandlerDescriptor(addresses, port, protocol, state, name, emptySet); 505 } 506 507 private <T> void addAll(final Collection<T> target, final Collection<T> source) 508 { 509 if (source != null) 510 { 511 target.addAll(source); 512 } 513 } 514 515 private ConnectionHandlerDescriptor getConnectionHandler(final AdministrationConnectorCfg adminConnector) 516 throws OpenDsException 517 { 518 final SortedSet<InetAddress> addresses = new TreeSet<>(getInetAddressComparator()); 519 520 final ConnectionHandlerDescriptor.Protocol protocol = ConnectionHandlerDescriptor.Protocol.ADMINISTRATION_CONNECTOR; 521 final ConnectionHandlerDescriptor.State state = ConnectionHandlerDescriptor.State.ENABLED; 522 523 addAll(addresses, adminConnector.getListenAddress()); 524 final int port = adminConnector.getListenPort(); 525 final Set<CustomSearchResult> emptySet = Collections.emptySet(); 526 return new ConnectionHandlerDescriptor(addresses, port, protocol, state, 527 INFO_CTRL_PANEL_CONN_HANDLER_ADMINISTRATION.get().toString(), emptySet); 528 } 529}