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