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