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