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