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