001 /*
002 * Copyright 2007-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 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 * System.out.println("The directory server supports the use of the " +
053 * "server-side sort request control.");
054 * }
055 * else
056 * {
057 * System.out.println("The directory server does not support the use of " +
058 * "the server-side sort request control.");
059 * }
060 * </PRE>
061 */
062 @NotMutable()
063 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
064 public final 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 private 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 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 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 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 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 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 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 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 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 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 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 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 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 boolean supportsExtendedOperation(final String extendedOperationOID)
469 {
470 return hasAttributeValue(ATTR_SUPPORTED_EXTENDED_OPERATION,
471 extendedOperationOID);
472 }
473
474
475
476 /**
477 * Retrieves the OIDs of the supported features advertised by the server root
478 * DSE.
479 *
480 * @return The OIDs of the supported features advertised by the server root
481 * DSE, or {@code null} if the server does not publish that
482 * information.
483 */
484 public String[] getSupportedFeatureOIDs()
485 {
486 return getAttributeValues(ATTR_SUPPORTED_FEATURE);
487 }
488
489
490
491 /**
492 * Indicates whether the directory server indicates that it supports the
493 * extended operation with the provided OID.
494 *
495 * @param featureOID The OID of the feature for which to make the
496 * determination. It must not be {@code null}.
497 *
498 * @return {@code true} if the server indicates that it supports the feature
499 * with the specified OID, or {@code false} if it does not.
500 */
501 public boolean supportsFeature(final String featureOID)
502 {
503 return hasAttributeValue(ATTR_SUPPORTED_FEATURE, featureOID);
504 }
505
506
507
508 /**
509 * Retrieves the supported LDAP protocol versions advertised by the server
510 * root DSE.
511 *
512 * @return The supported LDAP protocol versions advertised by the server
513 * root DSE, or {@code null} if the server does not publish that
514 * information.
515 */
516 public int[] getSupportedLDAPVersions()
517 {
518 final String[] versionStrs =
519 getAttributeValues(ATTR_SUPPORTED_LDAP_VERSION);
520 if (versionStrs == null)
521 {
522 return null;
523 }
524
525 final int[] versions = new int[versionStrs.length];
526 for (int i=0; i < versionStrs.length; i++)
527 {
528 try
529 {
530 versions[i] = Integer.parseInt(versionStrs[i]);
531 }
532 catch (final Exception e)
533 {
534 debugException(e);
535 // We couldn't parse the value as an integer.
536 return null;
537 }
538 }
539
540 return versions;
541 }
542
543
544
545 /**
546 * Indicates whether the directory server indicates that it supports the
547 * provided LDAP protocol version.
548 *
549 * @param ldapVersion The LDAP protocol version for which to make the
550 * determination.
551 *
552 * @return {@code true} if the server indicates that it supports the
553 * specified LDAP protocol version, or {@code false} if it does not.
554 */
555 public boolean supportsLDAPVersion(final int ldapVersion)
556 {
557 return hasAttributeValue(ATTR_SUPPORTED_LDAP_VERSION,
558 String.valueOf(ldapVersion));
559 }
560
561
562
563 /**
564 * Retrieves the names of the supported SASL mechanisms advertised by the
565 * server root DSE.
566 *
567 * @return The names of the supported SASL mechanisms advertised by the
568 * server root DSE, or {@code null} if the server does not publish
569 * that information.
570 */
571 public String[] getSupportedSASLMechanismNames()
572 {
573 return getAttributeValues(ATTR_SUPPORTED_SASL_MECHANISM);
574 }
575
576
577
578 /**
579 * Indicates whether the directory server indicates that it supports the
580 * specified SASL mechanism.
581 *
582 * @param mechanismName The name of the SASL mechanism for which to make the
583 * determination. It must not be {@code null}.
584 *
585 * @return {@code true} if the server indicates that it supports the
586 * specified SASL mechanism, or {@code false} if it does not.
587 */
588 public boolean supportsSASLMechanism(final String mechanismName)
589 {
590 return hasAttributeValue(ATTR_SUPPORTED_SASL_MECHANISM, mechanismName);
591 }
592
593
594
595 /**
596 * Retrieves the name of the directory server vendor, if available.
597 *
598 * @return The name of the directory server vendor, or {@code null} if the
599 * server does not publish that information.
600 */
601 public String getVendorName()
602 {
603 return getAttributeValue(ATTR_VENDOR_NAME);
604 }
605
606
607
608 /**
609 * Retrieves the directory server version string, if available.
610 *
611 * @return The directory server version string, or {@code null} if the server
612 * does not publish that information.
613 */
614 public String getVendorVersion()
615 {
616 return getAttributeValue(ATTR_VENDOR_VERSION);
617 }
618 }