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