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