001/* 002 * Copyright 2007-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk; 022 023 024 025import com.unboundid.util.NotMutable; 026import com.unboundid.util.ThreadSafety; 027import com.unboundid.util.ThreadSafetyLevel; 028 029import static com.unboundid.util.Debug.*; 030 031 032 033/** 034 * This class provides a data structure for representing the directory server 035 * root DSE. This entry provides information about the capabilities of the 036 * directory server, server vendor and version information, and published naming 037 * contexts. 038 * <BR><BR> 039 * Note a root DSE object instance represents a read-only version of an entry, 040 * so all read operations allowed for an entry will succeed, but all write 041 * attempts will be rejected. 042 * <BR><BR> 043 * <H2>Example</H2> 044 * The following example demonstrates the process for retrieving the root DSE 045 * of a directory server and using it to determine whether it supports the 046 * {@link com.unboundid.ldap.sdk.controls.ServerSideSortRequestControl}: 047 * <PRE> 048 * RootDSE rootDSE = connection.getRootDSE(); 049 * if (rootDSE.supportsControl( 050 * ServerSideSortRequestControl.SERVER_SIDE_SORT_REQUEST_OID)) 051 * { 052 * // The directory server does support the server-side sort control. 053 * } 054 * else 055 * { 056 * // The directory server does not support the server-side sort control. 057 * } 058 * </PRE> 059 */ 060@NotMutable() 061@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 062public final class RootDSE 063 extends ReadOnlyEntry 064{ 065 /** 066 * The name of the attribute that includes a set of URIs (likely in the form 067 * of LDAP URLs) of other servers that may be contacted if the target server 068 * is unavailable, as defined in RFC 4512 section 5.1. 069 */ 070 public static final String ATTR_ALT_SERVER = "altServer"; 071 072 073 074 /** 075 * The name of the attribute that specifies the DN that is the base of the 076 * LDAP changelog data, if available, as defined in draft-good-ldap-changelog. 077 */ 078 public static final String ATTR_CHANGELOG_DN = "changelog"; 079 080 081 082 /** 083 * The name of the attribute that may contain the change number for the first 084 * entry in the LDAP changelog. This is not defined in any public 085 * specification, but is provided by a number of servers which implement 086 * draft-good-ldap-changelog. 087 */ 088 public static final String ATTR_FIRST_CHANGE_NUMBER = "firstChangeNumber"; 089 090 091 092 /** 093 * The name of the attribute that may contain the change number for the last 094 * entry in the LDAP changelog, if available. This is not defined in any 095 * public specification, but is provided by a number of servers which 096 * implement draft-good-ldap-changelog. 097 */ 098 public static final String ATTR_LAST_CHANGE_NUMBER = "lastChangeNumber"; 099 100 101 102 /** 103 * The name of the attribute that may contain the change number for the last 104 * entry purged from the LDAP changelog, if available. This is not defined in 105 * any public specification, but is provided by a number of servers which 106 * implement draft-good-ldap-changelog. 107 */ 108 public static final String ATTR_LAST_PURGED_CHANGE_NUMBER = 109 "lastPurgedChangeNumber"; 110 111 112 113 /** 114 * The name of the attribute that includes the DNs of the public naming 115 * contexts defined in the server, as defined in RFC 4512 section 5.1. 116 */ 117 public static final String ATTR_NAMING_CONTEXT = "namingContexts"; 118 119 120 121 /** 122 * The name of the attribute that specifies the DN of the subschema subentry 123 * that serves the server root DSE, as defined in RFC 4512 section 4.2. 124 */ 125 public static final String ATTR_SUBSCHEMA_SUBENTRY = "subschemaSubentry"; 126 127 128 129 /** 130 * The name of the attribute that includes the names of the supported 131 * authentication password storage schemes, as defined in RFC 3112. 132 */ 133 public static final String ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME = 134 "supportedAuthPasswordSchemes"; 135 136 137 138 /** 139 * The name of the attribute that includes the OIDs of the request controls 140 * supported by the server, as defined in RFC 4512 section 5.1. 141 */ 142 public static final String ATTR_SUPPORTED_CONTROL = "supportedControl"; 143 144 145 146 /** 147 * The name of the attribute that includes the OIDs of the extended operations 148 * supported by the server, as defined in RFC 4512 section 5.1. 149 */ 150 public static final String ATTR_SUPPORTED_EXTENDED_OPERATION = 151 "supportedExtension"; 152 153 154 155 /** 156 * The name of the attribute that includes the OIDs of the features supported 157 * by the server, as defined in RFC 4512 section 5.1. 158 */ 159 public static final String ATTR_SUPPORTED_FEATURE = 160 "supportedFeatures"; 161 162 163 164 /** 165 * The name of the attribute that includes the OIDs of the LDAP protocol 166 * versions supported by the server, as defined in RFC 4512 section 5.1. 167 */ 168 public static final String ATTR_SUPPORTED_LDAP_VERSION = 169 "supportedLDAPVersion"; 170 171 172 173 /** 174 * The name of the attribute that includes the names of the SASL mechanisms 175 * supported by the server, as defined in RFC 4512 section 5.1. 176 */ 177 public static final String ATTR_SUPPORTED_SASL_MECHANISM = 178 "supportedSASLMechanisms"; 179 180 181 182 /** 183 * The name of the attribute that includes the name of the server vendor, 184 * as defined in RFC 3045. 185 */ 186 public static final String ATTR_VENDOR_NAME = "vendorName"; 187 188 189 190 /** 191 * The name of the attribute that includes the server version, as defined in 192 * RFC 3045. 193 */ 194 public static final String ATTR_VENDOR_VERSION = "vendorVersion"; 195 196 197 198 /** 199 * The set of request attributes to use when attempting to retrieve the server 200 * root DSE. It will attempt to retrieve all operational attributes if the 201 * server supports that capability, but will also attempt to retrieve specific 202 * attributes by name in case it does not. 203 */ 204 private static final String[] REQUEST_ATTRS = 205 { 206 "*", 207 "+", 208 ATTR_ALT_SERVER, 209 ATTR_CHANGELOG_DN, 210 ATTR_FIRST_CHANGE_NUMBER, 211 ATTR_LAST_CHANGE_NUMBER, 212 ATTR_LAST_PURGED_CHANGE_NUMBER, 213 ATTR_NAMING_CONTEXT, 214 ATTR_SUBSCHEMA_SUBENTRY, 215 ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME, 216 ATTR_SUPPORTED_CONTROL, 217 ATTR_SUPPORTED_EXTENDED_OPERATION, 218 ATTR_SUPPORTED_FEATURE, 219 ATTR_SUPPORTED_LDAP_VERSION, 220 ATTR_SUPPORTED_SASL_MECHANISM, 221 ATTR_VENDOR_NAME, 222 ATTR_VENDOR_VERSION, 223 }; 224 225 226 227 /** 228 * The serial version UID for this serializable class. 229 */ 230 private static final long serialVersionUID = -1678182563511570981L; 231 232 233 234 /** 235 * Creates a new root DSE object from the information in the provided entry. 236 * 237 * @param rootDSEEntry The entry to use to create this root DSE object. It 238 * must not be {@code null}. 239 */ 240 public RootDSE(final Entry rootDSEEntry) 241 { 242 super(rootDSEEntry); 243 } 244 245 246 247 /** 248 * Retrieves the directory server root DSE using the provided connection. 249 * 250 * @param connection The connection to use to retrieve the server root DSE. 251 * 252 * @return The directory server root DSE, or {@code null} if it is not 253 * available (e.g., the client does not have permission to read the 254 * entry). 255 * 256 * @throws LDAPException If a problem occurs while attempting to retrieve 257 * the server root DSE. 258 */ 259 public static RootDSE getRootDSE(final LDAPInterface connection) 260 throws LDAPException 261 { 262 final Entry rootDSEEntry = connection.getEntry("", REQUEST_ATTRS); 263 if (rootDSEEntry == null) 264 { 265 return null; 266 } 267 268 return new RootDSE(rootDSEEntry); 269 } 270 271 272 273 /** 274 * Retrieves a set of URIs for alternate servers that may be contacted if 275 * the current server becomes unavailable. 276 * 277 * @return A set of URIs for alternate servers that may be contacted if the 278 * current server becomes available, or {@code null} if the server 279 * does not publish that information. 280 */ 281 public String[] getAltServerURIs() 282 { 283 return getAttributeValues(ATTR_ALT_SERVER); 284 } 285 286 287 288 /** 289 * Retrieves the DN of the base entry for the directory server changelog 290 * information, if available. 291 * 292 * @return The DN of the base entry for the directory server changelog 293 * information, or {@code null} if the server does not publish that 294 * information or no changelog is available. 295 */ 296 public String getChangelogDN() 297 { 298 return getAttributeValue(ATTR_CHANGELOG_DN); 299 } 300 301 302 303 /** 304 * Retrieves the change number for the first entry contained in the LDAP 305 * changelog, if available. 306 * 307 * @return The change number for the first entry contained in the LDAP 308 * changelog, if available. 309 */ 310 public Long getFirstChangeNumber() 311 { 312 return getAttributeValueAsLong(ATTR_FIRST_CHANGE_NUMBER); 313 } 314 315 316 317 /** 318 * Retrieves the change number for the last entry contained in the LDAP 319 * changelog, if available. 320 * 321 * @return The change number for the last entry contained in the LDAP 322 * changelog, if available. 323 */ 324 public Long getLastChangeNumber() 325 { 326 return getAttributeValueAsLong(ATTR_LAST_CHANGE_NUMBER); 327 } 328 329 330 331 /** 332 * Retrieves the change number for the last entry purged from the LDAP 333 * changelog, if available. 334 * 335 * @return The change number for the last entry purged from the LDAP 336 * changelog, if available. 337 */ 338 public Long getLastPurgedChangeNumber() 339 { 340 return getAttributeValueAsLong(ATTR_LAST_PURGED_CHANGE_NUMBER); 341 } 342 343 344 345 /** 346 * Retrieves the DNs of the naming contexts provided by the directory server. 347 * 348 * @return The DNs of the naming contexts provided by the directory server, 349 * or {@code null} if the server does not publish that information. 350 */ 351 public String[] getNamingContextDNs() 352 { 353 return getAttributeValues(ATTR_NAMING_CONTEXT); 354 } 355 356 357 358 /** 359 * Retrieves the DN of the subschema subentry that serves the directory server 360 * root DSE. 361 * 362 * @return The DN of the subschema subentry that serves the directory server 363 * root DSE, or {@code null} if the server does not publish that 364 * information. 365 */ 366 public String getSubschemaSubentryDN() 367 { 368 return getAttributeValue(ATTR_SUBSCHEMA_SUBENTRY); 369 } 370 371 372 373 /** 374 * Retrieves the names of the authentication password storage schemes 375 * supported by the server. 376 * 377 * @return The names of the authentication password storage schemes supported 378 * by the server, or {@code null} if the server does not publish 379 * that information. 380 */ 381 public String[] getSupportedAuthPasswordSchemeNames() 382 { 383 return getAttributeValues(ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME); 384 } 385 386 387 388 /** 389 * Indicates whether the directory server indicates that it supports the 390 * specified authentication password storage scheme. 391 * 392 * @param scheme The name of the authentication password storage scheme for 393 * which to make the determination. It must not be 394 * {@code null}. 395 * 396 * @return {@code true} if the directory server indicates that it supports 397 * the specified authentication password storage scheme, or 398 * {@code false} if it does not. 399 */ 400 public boolean supportsAuthPasswordScheme(final String scheme) 401 { 402 return hasAttributeValue(ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME, 403 scheme); 404 } 405 406 407 408 /** 409 * Retrieves the OIDs of the supported request controls advertised by the 410 * server root DSE. 411 * 412 * @return The OIDs of the supported request controls advertised by the 413 * server root DSE, or {@code null} if the server does not publish 414 * that information. 415 */ 416 public String[] getSupportedControlOIDs() 417 { 418 return getAttributeValues(ATTR_SUPPORTED_CONTROL); 419 } 420 421 422 423 /** 424 * Indicates whether the directory server indicates that it supports the 425 * request control with the provided OID. 426 * 427 * @param controlOID The OID of the control for which to make the 428 * determination. It must not be {@code null}. 429 * 430 * @return {@code true} if the server indicates that it supports the request 431 * control with the specified OID, or {@code false} if it does not. 432 */ 433 public boolean supportsControl(final String controlOID) 434 { 435 return hasAttributeValue(ATTR_SUPPORTED_CONTROL, controlOID); 436 } 437 438 439 440 /** 441 * Retrieves the OIDs of the supported extended operations advertised by the 442 * server root DSE. 443 * 444 * @return The OIDs of the supported extended operations advertised by the 445 * server root DSE, or {@code null} if the server does not publish 446 * that information. 447 */ 448 public String[] getSupportedExtendedOperationOIDs() 449 { 450 return getAttributeValues(ATTR_SUPPORTED_EXTENDED_OPERATION); 451 } 452 453 454 455 /** 456 * Indicates whether the directory server indicates that it supports the 457 * extended operation with the provided OID. 458 * 459 * @param extendedOperationOID The OID of the extended operation for which 460 * to make the determination. It must not be 461 * {@code null}. 462 * 463 * @return {@code true} if the server indicates that it supports the extended 464 * operation with the specified OID, or {@code false} if it does not. 465 */ 466 public boolean supportsExtendedOperation(final String extendedOperationOID) 467 { 468 return hasAttributeValue(ATTR_SUPPORTED_EXTENDED_OPERATION, 469 extendedOperationOID); 470 } 471 472 473 474 /** 475 * Retrieves the OIDs of the supported features advertised by the server root 476 * DSE. 477 * 478 * @return The OIDs of the supported features advertised by the server root 479 * DSE, or {@code null} if the server does not publish that 480 * information. 481 */ 482 public String[] getSupportedFeatureOIDs() 483 { 484 return getAttributeValues(ATTR_SUPPORTED_FEATURE); 485 } 486 487 488 489 /** 490 * Indicates whether the directory server indicates that it supports the 491 * extended operation with the provided OID. 492 * 493 * @param featureOID The OID of the feature for which to make the 494 * determination. It must not be {@code null}. 495 * 496 * @return {@code true} if the server indicates that it supports the feature 497 * with the specified OID, or {@code false} if it does not. 498 */ 499 public boolean supportsFeature(final String featureOID) 500 { 501 return hasAttributeValue(ATTR_SUPPORTED_FEATURE, featureOID); 502 } 503 504 505 506 /** 507 * Retrieves the supported LDAP protocol versions advertised by the server 508 * root DSE. 509 * 510 * @return The supported LDAP protocol versions advertised by the server 511 * root DSE, or {@code null} if the server does not publish that 512 * information. 513 */ 514 public int[] getSupportedLDAPVersions() 515 { 516 final String[] versionStrs = 517 getAttributeValues(ATTR_SUPPORTED_LDAP_VERSION); 518 if (versionStrs == null) 519 { 520 return null; 521 } 522 523 final int[] versions = new int[versionStrs.length]; 524 for (int i=0; i < versionStrs.length; i++) 525 { 526 try 527 { 528 versions[i] = Integer.parseInt(versionStrs[i]); 529 } 530 catch (final Exception e) 531 { 532 debugException(e); 533 // We couldn't parse the value as an integer. 534 return null; 535 } 536 } 537 538 return versions; 539 } 540 541 542 543 /** 544 * Indicates whether the directory server indicates that it supports the 545 * provided LDAP protocol version. 546 * 547 * @param ldapVersion The LDAP protocol version for which to make the 548 * determination. 549 * 550 * @return {@code true} if the server indicates that it supports the 551 * specified LDAP protocol version, or {@code false} if it does not. 552 */ 553 public boolean supportsLDAPVersion(final int ldapVersion) 554 { 555 return hasAttributeValue(ATTR_SUPPORTED_LDAP_VERSION, 556 String.valueOf(ldapVersion)); 557 } 558 559 560 561 /** 562 * Retrieves the names of the supported SASL mechanisms advertised by the 563 * server root DSE. 564 * 565 * @return The names of the supported SASL mechanisms advertised by the 566 * server root DSE, or {@code null} if the server does not publish 567 * that information. 568 */ 569 public String[] getSupportedSASLMechanismNames() 570 { 571 return getAttributeValues(ATTR_SUPPORTED_SASL_MECHANISM); 572 } 573 574 575 576 /** 577 * Indicates whether the directory server indicates that it supports the 578 * specified SASL mechanism. 579 * 580 * @param mechanismName The name of the SASL mechanism for which to make the 581 * determination. It must not be {@code null}. 582 * 583 * @return {@code true} if the server indicates that it supports the 584 * specified SASL mechanism, or {@code false} if it does not. 585 */ 586 public boolean supportsSASLMechanism(final String mechanismName) 587 { 588 return hasAttributeValue(ATTR_SUPPORTED_SASL_MECHANISM, mechanismName); 589 } 590 591 592 593 /** 594 * Retrieves the name of the directory server vendor, if available. 595 * 596 * @return The name of the directory server vendor, or {@code null} if the 597 * server does not publish that information. 598 */ 599 public String getVendorName() 600 { 601 return getAttributeValue(ATTR_VENDOR_NAME); 602 } 603 604 605 606 /** 607 * Retrieves the directory server version string, if available. 608 * 609 * @return The directory server version string, or {@code null} if the server 610 * does not publish that information. 611 */ 612 public String getVendorVersion() 613 { 614 return getAttributeValue(ATTR_VENDOR_VERSION); 615 } 616}