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