UnboundID LDAP SDK for Java 3.2.1

We have just released the 3.2.1 version of the UnboundID LDAP SDK for Java. It is available for download from the LDAP.com website, as well as from GitHub, SourceForge, or the Maven Central Repository. You can get a full list of changes included in this release from the release notes. The Commercial Edition release notes also provide information about additional changes only included in the Commercial Edition. Some of the most significant changes in both the Standard Edition and the Commercial Edition include
  • Updated the documentation to indicate that, as a result of Ping Identity's acquisition of UnboundID, all non-public feedback, feature enhancements, support requests, and other kinds of communication should now be sent to ldapsdk-support@pingidentity.com instead of ldapsdk-support@unboundid.com. We also now recommend using the GitHub issue tracker over the SourceForge mailing lists and discussion forums for bug reports and feature requests.
  • Fixed a bug in the RDN parsing code that could cause multiple consecutive spaces in the middle of an attribute value to be condensed down to a single space. The string representation of the RDN was preserved correctly, but the methods used to retrieve attribute values as a string or byte array could return values that were missing spaces.
  • Provided better handling for InterruptedException. A thread's interrupted state will now be preserved for cases in which the LDAP SDK consumes an InterruptedException without doing something to handle it.
  • Fixed a bug in the support for the SASL ANONYMOUS mechanism that could cause the trace string to be omitted from the encoded bind request.
  • Updated the searchrate tool to provide support for generic controls, as well as specific support for the assertion, simple paged results, and server-side sort request controls.
  • Updated the authrate tool to add a new --bindOnly argument that allows you to indicate that the tool should only perform bind operations, rather than a search to find the entry and then a bind as that user. The base DN pattern will be used to construct the bind DN.
  • Updated the authrate tool to provided support for generic search and bind controls, as well as specific support for the authorization identity and password policy request controls.
  • Updated the search-and-modrate tool to provide support for generic search and modify controls, as well as specific support for the assertion, simple paged results, permissive modify, pre-read, and post-read request controls.
  • Added a Schema.getSchema method that can read schema information in LDIF form from an input stream.
  • Updated support for the GSSAPI SASL mechanism to make it possible to indicate in the generated configuration file whether the client should act as an initiator or an acceptor.
  • Updated the identify-unique-attribute-conflicts tool to include a time limit in search requests intended to determine whether a unique attribute value may also be in use in any other entries. This can help limit the effect of running the tool against a server that is not configured with the appropriate indexes needed to ensure that equality searches targeting the unique attributes can be processed efficiently.
Some of the additional changes only available in the Commercial Edition include:
  • Added a new version of the ldapsearch tool that provides a lot of additional functionality over the version provided in the Standard Edition. It includes much better output formatting (including support for alternate output formats like JSON, CSV, and tab-delimited text), support for a number of data transformations, more robust connection handling, support for referrals, support for a large number of search and bind controls, support for administrative sessions, support for unsolicited notifications, the ability to process multiple searches with search criteria provided in filter or LDAP URL files, rate limiting, and the ability to send results to a specified output file (or a separate output file per search).
  • Implemented caching for the matching rule instance used when requesting the jsonObjectExactMatch matching rule. This matching rule only exists in the Commercial Edition and needs to be loaded via reflection.
  • Updated the access and error log parsing APIs to include support for the triggeredByConn and triggeredByOp log fields used to indicate that the message is associated with the indicated operation.

The Story of UnboundID

At the end of 2016, I ceased to be an employee of UnboundID and became an employee of Ping Identity. Ping acquired UnboundID in early August of 2016, but most UnboundID staff remained employees of that company through the end of the year (mostly for bookkeeping convenience). As a co-founder, I was with UnboundID from the beginning. Here is our story.

Once upon a time, Sun Microsystems had the best LDAP directory server on the market. The 5.1 and 5.2 releases of the Directory Server Enterprise Edition (DSEE) product, which introduced multi-master replication and 64-bit support, respectively, were very exciting.

But then for some reason, Sun’s directory server engineering team seemed to contract a chronic case of inertia, in which everyone was content to rest on their laurels. It certainly wasn’t because the product had reached perfection, nor from a lack of ideas for improvement. After a while, I became frustrated with the lack of progress, and I wrote a hundred-plus-page document (which became known as the “directory manifesto”) that was full of things that we could do to improve the product. It had plenty of low-hanging fruit that would address pain points that customers were experiencing and lots of bigger ideas to help ensure our continued dominance of the high-end directory server market. But to no avail.

Eventually, I was able to nag the right people long enough to let me start working on a new directory server that was intended to be a DSEE replacement. And thus I became the first developer working on what would become OpenDS. Sun was committed to open sourcing all their software, from Solaris to Java to all of their enterprise software, and before long, we released OpenDS under the same CDDL license that they initially created for OpenSolaris.

At that time, Sun’s Directory Server engineering team was mostly split between Austin, Texas and Grenoble, France. In 2007, someone got the idea that it would be good to have it headquartered all in one place, and Grenoble was chosen as that one place. As a result, the five U.S. employees most closely connected with OpenDS were laid off: director of engineering Steve Shoaff, marketing lead Don Bowen, engineering manager David Ely, open source community manager Trey Drake, and myself as architect.

It didn’t take the five of us long to decide that we wanted to create a new company developing on top of the OpenDS codebase. We were still passionate about the product and excited about the opportunities that it could afford, and we planned to contribute back to the open source community. We even followed through on that with a handful of commits within a couple of weeks of the layoff. But then some nastiness arose between us and Sun’s management that I don’t want to get into here, and it became clear that we were no longer welcome participants.

So by the time we founded UnboundID (on December 17, 2007), we were to be competing against Sun. We’d comply with the terms of the open source license when altering existing code, but newly-created files would be our own private intellectual property, as allowed by the CDDL. We would, of course, also go head-to-head with other directory server vendors, like Oracle (who bought Sun within a few months of our departure), IBM, Microsoft, and CA. And we’d be up against open source offerings like OpenLDAP and the 389 Directory Server. We should’ve had no chance. And yet we were shockingly optimistic. We had a lot of ideas, a lot of drive, and dare I say a pretty good amount of talent.

Upon officially forming the company, David, Trey, and I worked furiously to make improvements to the codebase. We made dramatic improvements in performance, concurrency, and scalability. We added killer features, like support for transactions, filtered logging, change subscriptions, data transformations, data integrity checksums, and some new controls and extended operations. We made the server easier to manage by improving the out-of-the-box configuration, refined the command-line and interactive text-based interfaces, and added a web-based administration console.

We also created a new Java-based API for interacting with LDAP servers, because the existing options sucked. Before we released the UnboundID LDAP SDK for Java, you could basically choose between the horrible, confusing clunkiness of JNDI (where LDAP support is bolted on as an afterthought), or the buggy and no-longer-maintained Netscape Directory API. We wanted to create an API that made it easy to write applications that could take full advantage of any LDAP server, including the enhanced functionality we were building into our own software.

While David, Trey, and I were churning out the code, Steve and Don were working to sell it. And they did. Amazingly, we got our first customer within a matter of months: a large network equipment provider that supplied telephone companies with the equipment used to run their data centers. They loved our software, our enthusiasm, our ability to react quickly, and our willingness to put our source code in escrow so they wouldn’t be screwed if we went out of business. And before long, a number of big telcos were kicking the tires on our stuff and salivating at the idea of a modern, high-powered, feature-rich, and administrator-friendly directory service.

This first customer was a huge win for us. They resold our software and provided first-line support, which helped alleviate any downstream concerns about our viability. They declared our software to be carrier-grade, which served as validation to other potential customers in other industries. And it was also nice to be able to start getting a paycheck.

Plus, we were able to leverage this deal to get good terms on an initial round of funding from an investor. We were able to hire more people (many of whom were former colleagues from Sun who were all too happy to jump ship from their new Oracle overlords), and we started working on new products. David took on the Synchronization Server, and I started on the Directory Proxy Server.

The Synchronization Server provides a way to mirror the contents of two or more data repositories, so that changes made in one system appear in the other systems, usually in a matter of milliseconds. It can do one-way or bidirectional synchronization. It can synchronize all the data or just a configurable subset. And you can connect to a number of different types of repositories, including LDAP directory servers (both UnboundID and non-UnboundID), relational databases, NoSQL databases, and more (plus an API for developing your own support for additional types of data stores). It’s ideal for migrating data from your existing repository into the UnboundID Directory Server, and for keeping both infrastructures in sync for whatever length of time is necessary to complete the migration, or indefinitely if you want to keep both systems up and running.

As its name implies, the Directory Proxy Server is an LDAP proxy server. In the simplest deployments, it allows you to achieve better performance and higher availability through load balancing and advanced health checking techniques. In larger deployments, you can use entry balancing to transparently split data up into multiple sets (much like database sharding) for even greater scalability. It can also transform requests and responses as they pass between clients and backend directory servers, and you can do this on a per-application basis in case some clients have different expectations for how the data should look or how the server should behave.

We continued to grow. We sold more software. We gained more customers. We hired more employees. We wrote more code. But sadly, we also suffered some losses. Trey decided it was time for him to move on, so he left the company. But even more tragically, Don Bowen passed away in late 2009. He’d been diagnosed with brain cancer a mere three days after we founded the company, and somehow he continued to make incredible contributions toward our success for over a year and a half. I met Don in my first job out of college, at Caterpillar, where he introduced me to the world of LDAP. Within a few months, he’d gotten an offer to join the Baltimore-based startup (initially called B2B Communications, but later renamed TidePoint Corporation) and he took me with him. When that went south, we went our separate ways, only to meet up again when we both joined Sun at about the same time. We were friends as well as colleagues, and a tremendous amount of who I am today is because of Don.

And the work goes on. As more customers migrated from existing environments and deployed into new environments, we realized that we needed to provide public interfaces to allow our software to be customized, so we created the Server SDK. Our server products had always been very extensible and componentized, but before the Server SDK, we were the only ones who could take advantage of that. The Server SDK made it possible for customers to write their own extensions to customize the behavior of the server, from intercepting and altering operation requests and responses, to creating new loggers, password validators, extended operations, SASL mechanisms, sync sources and destinations, proxy transformations, and more. The initial intention was to only make the Server SDK available to customers who’d gone through at least some kind of training (it allows you to run custom code inside the server, so there’s a chance that a buggy extension could make the server unusable), and I really wish we’d stuck to that more than we did. But for the most part, it was a hit with customers, and an even bigger hit with the sales engineers helping them evaluate and then migrate to our software.

We also introduced a couple of additional server products: the Analytics Engine and the Data Broker. The Analytics Engine (formerly called the Metrics Engine) provides simple, graphical access to all kinds of historical information about the operation of the server broken down in all kinds of ways (e.g., the number of requests per second of each operation type, and a breakdown of their result codes and processing times), along with metrics from the underlying system like CPU, disk, and network utilization. The Data Broker provides several REST-based interfaces to interact with the environment, including support for OAuth 2 and OpenID Connect (for authentication, authorization, and federation), and SCIM (for data access). As much as I love LDAP and will continue to tout its superiority over HTTP, the kids these days are all about the web APIs, so we must oblige.

But even as we worked on new products, the Directory Server continued to grow and improve. I am particularly passionate about security, so that’s been a big focus of mine over the last several years. We added support for data encryption, several two-factor authentication mechanisms, more password storage schemes and password validators, sensitive attributes, retired passwords, password reset tokens, improved account lockout, signed logs, and more. But we also added a lot of non-security-related features, like JSON support, alarms and gauges, soft deletes, assured replication, and indexing improvements. It’s gotten faster, easier to use and administer, and just plain better.

On the whole, we’ve had an unbelievable run. We did have one down year with less-than-stellar sales, but for all other years, we reached or exceeded our goals. That continued through 2016, which was one of our best years ever (even if you ignore the whole “our company was bought” thing). We certainly weren’t floundering, and we weren’t really even looking to be acquired. We had partnered with Ping Identity on a number of deals in the past, as each company’s software complemented the other’s very well without too much overlap. And then Ping was acquired by Vista Equity Partners, who were looking for other opportunities to get into identity management, and then people started talking and it all sort of became a three-way deal, with the UnboundID acquisition by Ping Identity following Ping’s own acquisition within a couple of weeks.

So what’s next for the bigger, better Ping Identity? I can’t get into any specifics, but we’ve got a lot of great things in the works. Most of the UnboundID staff, and I believe all of the technical staff, are continuing on into Ping. Some people are changing roles (many moving up, others moving laterally), but my job isn’t really changing all that much. I’m still writing code, and hope that continues far into the future. Some of our product names have changed (for example, it’s now the Ping Identity Directory Server rather than the UnboundID Directory Server), and some haven’t (it’s still the UnboundID LDAP SDK for Java), but we’re still working to ensure that they remain the best products out there. So I need to get back to work.

P.S. I know that the only people I mentioned by name in this walk down memory lane are the UnboundID founders. I certainly don’t mean to imply that we’re the only ones responsible for or vital to the company’s success. There are so many other people that made big contributions to the company that I can’t list them all without fear of leaving someone out, without fear of mentioning someone who’d rather be left out, and without fear of making this long post even longer. So let me just say that if you worked for UnboundID in any capacity, you have my sincerest thanks.



UnboundID LDAP SDK for Java 3.2.0

We have just released the 3.2.0 version of the UnboundID LDAP SDK for Java. It is available for download via the LDAP.com website or from GitHub, as well as the Maven Central Repository.

You can get a full list of changes included in this release from the release notes (or the Commercial Edition release notes for changes specific to the Commercial Edition). Some of the most significant changes include:

  • Added a new transform-ldif tool that can be used to apply a number of transformations to data in an LDIF file. This includes the ability to scramble, replace, redact, or exclude a specified set of attributes; to replace existing values for a specified attribute; to use a sequential counter for values of a specified attribute; to add a given set of values to entries matching specified criteria; to exclude entries matching specified criteria; to rename attributes; to replace the base DN for entries in a specified subtree; and to flatten a DIT.

  • Updated all classes that offer a public void close() method that doesn't throw any exceptions other than a possible IOException so that they implement the java.io.Closeable interface. This includes classes like LDAPConnection, LDAPConnectionPool, LDIFReader, LDIFWriter, and all EntrySource implementations. This allows code using these classes to take advantage of the try-with-resources facility introduced in Java SE 7.

  • Added support for parsing entries that contain information about the operations processed in the server for servers that support the syntax described in draft-chu-ldap-logschema-00.

  • Updated the modrate tool to make a number of improvements, including support for a number of controls, the ability to replace multiple values rather than just a single value, or the ability to perform an increment modification rather than a replace modification.

  • Added a new JSONBuffer class that can be used to efficiently construct the string representation of a JSON object, and a JSONObjectReader class that can be used to read JSON objects from an input stream. Added the ability to generate formatted, multi-line string representations of JSON objects with improved human readability.

  • Updated the LDIF reader to make it possible to specify the character set to use when reading data. Updated the LDIF writer to make it possible to automatically include a comment below any base64-encoded values that provides a non-base64-encoded representation (with special characters escaped) of the preceding value.

  • Updated the in-memory directory server to support the LDAP no-operation control as described in draft-zeilenga-ldap-noop-12.

  • Added a new base64 command-line tool that can be used to encode and decode data using the base64 format.

  • Dramatically improved the robustness of the identify-references-to-missing-entries and identify-unique-attribute-conflicts tools.

  • Updated the argument parser to add support for subcommands with their own distinct set of arguments.

  • Added support for timestamp arguments, which can be used to specify timestamps in either the generalized time syntax (including the time zone), or in a number of formats that indicate a time in the local time zone.

  • Updated the command-line tool API to provide the ability to default to interactively prompt for passwords that may be needed but not provided, and to send output to a specified file.

  • Updated the rate adjustor so that generated sample rate files include a number of additional examples for common patterns like square, stairstep, sine, sawtooth, triangle, and hockey stick.


UnboundID LDAP SDK for Java 3.1.1

We have just released the 3.1.1 version of the UnboundID LDAP SDK for Java. It is available for download via the LDAP.com website or from GitHub, as well as the Maven Central Repository.

This is a relatively minor update release, and you can get a full list of changes from the release notes (or the Commercial Edition release notes for changes specific to the Commercial Edition). Some of the most significant changes include:

  • Updated the AddRequest constructor that allows you to create a request from an LDIF entry. It will now accept an LDIF add change record (including the "changeytpe: add" line, and optionally including controls) in addition to an LDIF entry.

  • Added two new LDAP listener request handler implementations that can be used to limit the load that clients can leverage against a listener. One implementation allows you to limit the number of requests that may be processed concurrently, while the other allows you to limit the overall rate (in operations per second) at which requests may be processed.

  • Fixed a bug in which the LDAP connection pool statistics were not always properly updated for a failed attempt to create a new connection for the pool.

  • Added a new --helpSASL argument for LDAP command-line tools that support authentication. This argument obtains a list of the supported SASL mechanisms and the options that are available for each.

  • Updated the command-line argument parser to provide support for using a properties file to supply the default values for arguments not explicitly provided on the command line. Tools that support this feature now include a --generatePropertiesFile argument that can be used to generate a template with the supported properties for that tool.

  • Updated the command-line argument parser to support grouping related sets of arguments together in the usage information.


UnboundID LDAP SDK for Java 3.1.0

We have just released the 3.1.0 version of the UnboundID LDAP SDK for Java. It is available for download via the LDAP.com website or from GitHub, as well as in the Maven Central Repository. The release notes provide complete details about the changes in this release, but some of the major changes include:

  • Added the ability to launch command-line tools in an interactive mode, in which the user will be prompted for details needed to connect and authenticate to the target directory server (if applicable for that tool), as well as for any required arguments. The tool will then display a table allowing the user to customize values for all of the arguments, and the user can run the tool with the desired settings or merely display the non-interactive command line that would be used to run with those options.

  • Updated the LDAP debugger and in-memory directory server tools to provide the ability to automatically generate source code for any client requests that they receive. This can be helpful when porting existing LDAP-enabled applications to use the UnboundID LDAP SDK for Java.

  • Updated the LDAP connection pool to make it possible to configure a minimum available connection goal. If a goal is set, then the connection pool will try to maintain at least that many connections available for immediate use. This can help reduce the need to create new connections on demand under periods of heavy load.

  • Added support for LDIF translators that can be used to transform LDIF change records when reading from or writing to LDIF. These translators are particularly helpful when using multiple threads to read or write change records in parallel.

  • Improved compatibility with servers that don't support the most recent TLS implementation and don't correctly handle TLS client hello messages that reference the newer protocol.

  • Updated the LDAP connection pool health check mechanism to provide support for validating a connection after authentication has completed. It was previously only possible to verify a connection after it was established but before it was authenticated. Added a new health check implementation that can check for various password policy-related conditions (e.g., a password that has expired or is about to expire), and another new aggregate health check that can invoke several health checks as a single unit.

  • Improved the LDAP SDK's handling of connection timeouts so that an unsuccessful connection attempt is less likely to block for longer than the configured timeout.

  • Deprecated the LDAPConnectionOptions auto-reconnect option. This option has always been very fragile and useful only in very limited circumstances. The functionality is still present (and will continue to be available in) the LDAP SDK, but applications are strongly recommended to use a connection pool, even when only a single connection is needed, because it provides much better and more reliable support for dealing with connectivity problems.

  • Added support for specifying a number of additional options when authenticating with the GSSAPI SASL mechanism, including the ability to obtain credentials from a keytab.

  • Added a new Entry.applyModifyDN method that can update the client-side representation of entry to reflect the changes that would be applied by a given modify DN operation. This updates both the entry DN and the corresponding attribute values in the entry.

  • Updated the in-memory directory server and the LDAP listener framework to make it possible to configure a maximum number of concurrent connections. You can also specify an entry to use as the in-memory directory server's root DSE.


UnboundID LDAP SDK for Java 3.0.0

We have just released the 3.0.0 version of the UnboundID LDAP SDK for Java. It is available for download via the LDAP.com website or from GitHub. There are a few pretty significant announcements to accompany this release:

  • The Commercial Edition of the LDAP SDK is now open source under the GPLv2 and LGPLv2.1 licenses. The Commercial Edition contains everything in the Standard Edition, plus a lot of additional functionality that is specifically intended for use in interacting with UnboundID server products.

  • The source code and packaged releases are now available on GitHub at https://github.com/UnboundID/ldapsdk. We will continue to maintain the repository, mailing lists, and discussion forum at SourceForge, but GitHub is now the recommended public repository for the LDAP SDK source code. Both public repositories now contain the Commercial Edition code along with the code for the Standard Edition and the Minimal Edition.

  • The Commercial Edition and Minimal Edition releases of the LDAP SDK are now in the Maven Central Repository. Both have a GroupId of "com.unboundid". The Commercial Edition has an ArtifactId of "unboundid-ldapsdk-commercial-edition", and the Minimal Edition has an ArtifactId of "unboundid-ldapsdk-minimal-edition". Previously, only the Standard Edition was available (GroupId "com.unboundid" and ArtifactId "unboundid-ldapsdk").

The following additional features, bug fixes, and enhancements are also included in this release:

  • The LDAP SDK now supports a JSON-based configuration syntax that can be used to specify a number of properties used to create LDAP connections and connection pools. It can include information about which servers to use (and if there are multiple servers, how to choose between them), how to authenticate (via simple authentication or several SASL mechanisms), how to secure the communication, and a number of other properties.

  • You can now manually invoke a synchronous health check against a connection pool, optionally with a different health check mechanism than is configured for the pool.

  • Improved the mechanism used to enforce a connect timeout. If a timeout occurs, it may be possible to close the associated socket and terminate the background connect thread more quickly.

  • You can now specify an alternate certificate key and/or trust store format (e.g., PKCS12 rather than the default of JKS) when launching the in-memory directory server from the command line.

  • There is improved support for command-line argument parsing, including support for arguments that provide information about LDAP controls, and better support for validating common argument formats.

  • Update the default settings for LDAP connection pools to eliminate the potential for the pool to block for up to five seconds if a connection is needed but none is immediately available.

  • When using value patterns (as in tools like searchrate, modrate, authrate, etc.), it is now possible to provide a path to a file whose lines should be accessed in sequential order. It was previously only possible to access file contents in random order.

  • The identify-unique-attribute-conflicts example tool now supports an optional filter. If provided, the tool will only report conflicts in entries matching that filter.

  • Ensure that connection pool statistics are properly updated to reflect connections closed as a result of a health check failure.

  • Fix a bug that could prevent the LDIF parser from using the correct matching rule for attributes if it is provided with access to an LDAP schema.

  • Fix a null pointer exception that could be thrown when attempting to retrieve the set of required or optional attributes from an object class definition if the associated schema is missing definitions for any of the superior object classes.

  • The Commercial Edition of the LDAP SDK has been updated with support for a number of new controls and extended operations, a filter syntax for searching inside attribute values that represent JSON objects, and other enhancements.


The New LDAP.com and a New LDAP SDK Release

Today, UnboundID is unveiling a new LDAP.com website, in addition to a revamp of the company's main UnboundID.com site. LDAP.com is the new home for the UnboundID LDAP SDK for Java, but it's also intended to be a general resource for all things LDAP. It includes information about many other LDAP APIs for a wide range of programming languages, as well as a number of commercial and open source LDAP server offerings.

LDAP.com has a lot of information about LDAP, including in-depth descriptions of protocol operations, key data structures like distinguished names and search filters, the LDIF format, and a glossary of LDAP terms. It also provides a pretty comprehensive list of LDAP specifications and reference documents, including RFCs and IETF drafts, as well as result code and OID references.

We're also releasing a new 2.3.8 version of the UnboundID LDAP SDK for Java. This is a minor release with only a couple of feature enhancements and bug fixes, including:

  • We've added a new Filter.simplifyFilter method that can be used to rearrange search filters so that they can be better optimized and processed more efficiently by many directory servers. This primarily involves simplification of the elements inside AND and OR filters, like removing unnecessary nesting (e.g., if an AND filter is nested inside another AND filter, then the elements inside the inner AND filter are moved into the outer filter), getting rid of duplicate elements, and replacing an AND or OR filters containing a single element with just that element. You can optionally re-order the elements inside an AND or an OR filter in a way that will make elements that are generally more efficient to process come before those that are generally less efficient to parse.

  • We've added a utility class for working with and comparing object identifiers (OIDs).

  • We fixed a thread-safety bug in the in-memory directory server.

  • The LDAP SDK document now contains information about a number of LDAP-related specifications defined in RFCs and Internet Drafts, as well as result code and OID reference documents.

The new 2.3.8 release of the LDAP SDK is available for download on LDAP.com or from the SourceForge project page. It's also available in the Maven Central Repository.


UnboundID LDAP SDK for Java 2.3.7

We have just released the 2.3.7 version of the UnboundID LDAP SDK for Java. You can get the latest release online at the UnboundID Website, the SourceForge project page, or in the Maven Central Repository.

Complete release note information is available online at on the UnboundID website, but some of the most significant changes include:

  • Updated the logic used to select the TLS protocols to use for secure communication. SSLv3 is now disabled by default in response to the recent POODLE bug. On IBM JVMs, the set of enabled TLS protocols should be more broadly compatible with earlier TLS versions when support for TLSv1.1 or TLSv1.2 is enabled.

  • Added the ability to perform improved SSLSocket validation, which makes it possible to perform certificate hostname validation in a more secure and convenient manner than was previously available. It is also now possible to get access to the SSL session associated with a connection secured via SSL/TLS or StartTLS.

  • Added a new server set that can work in a DNS round-robin configuration, in which multiple IP addresses are associated with the same resolvable name.

  • Added an LDAPConnectionPool.shrinkPool method that can be used to reduce the number of currently-available connections to a specified number.

  • Improved support for class inheritance in the LDAP SDK persistence framework. If one class marked with @LDAPObject is a subclass of another class marked with @LDAPObject, then the logic used to construct the entry's DN for instances of the subclass may be inherited from the superclass. Also, DN fields and entry fields will be properly handled in subclasses, and improvements have been made in requesting specific attributes to include in search result entries.

  • Added a new interceptor API to the in-memory directory server. This API can be used to alter or reject an LDAP request before it is processed by the server, to alter or suppress search result entries or references, and to alter LDAP results before they are returned to the client.

  • Updated the searchrate, modrate, authrate, and search-and-mod-rate tools to support altering the rate at which they process operations over time. Also, update these tools to make it possible to programmatically interrupt their processing.

  • Improved support for automatic referral following and auto-reconnect to ensure that the newly-established connection will properly use StartTLS if the original connection had successfully used StartTLS to secure its communication.

  • Fixed a bug in the Entry.applyModifications method that could cause valid modifications to be rejected if those modifications targeted attributes used in the entry's DN but would not actually have resulted in a change to the entry DN.

  • Fixed a bug in the Entry.diff method in which, if provided with a specific set of attributes to examine, the method would not examine variants of those attributes containing attribute options.

  • Fixed a potential null pointer exception that could arise as a result of a race condition in the course of closing a connection. Fixed a potential illegal argument exception that could arise when closing a connection pool if multiple concurrent threads were used to close the connections but no connections were currently available in the pool.


UnboundID LDAP SDK for Java 2.3.6

We have just released the 2.3.6 version of the UnboundID LDAP SDK for Java. You can get the latest release online at the UnboundID Website or the SourceForge project page, and it's also available in the Maven Central Repository.

This is primarily a maintenance release, containing bug fixes and some minor enhancements over the 2.3.5 version. A fully copy of the release notes for this version may be found on the UnboundID website, but some of the most notable changes include:

  • It is now possible to create a connection pool with a health check, without the need to set the health check after the pool has been created. The primary benefit of this approach is that the health check will be used for the initial set of connections that are established when the pool is created.

  • The LDIF change record implementations have been updated to add support for change records that include request controls.

  • Update the GSSAPI and DIGEST-MD5 SASL bind requests to support the use of the integrity and confidentiality quality of protection modes.

  • Improve support for processing asynchronous operations so that it is possible to invoke an asynchronous add, compare, delete, modify, or modify DN operation without needing to provide a result listener if the result will be accessed using the Future API. Also update the connection pool to make it possible to invoke multiple add, compare, delete, modify, modify DN, and/or search operations concurrently over the same connection as asynchronous operations.

  • Ensure that the thread-local connection pool uses the LDAPConnection.isConnected method as further verification that a connection is still established before attempting to use it.

  • Fix a bug in the in-memory directory server that prevented the updated values of certain attributes (e.g., modifiersName and modifyTimestamp) from appearing in the entry returned in a post-read response control.

  • Fix a potential thread safety bug in the get entry connection pool health check.


UnboundID LDAP SDK for Java 2.3.5

We have just released the 2.3.5 version of the UnboundID LDAP SDK for Java. You can get the latest release online at the UnboundID website or the SourceForge project page, and it's also available in the Maven Central Repository.

There are a lot of improvements in this release over the 2.3.4 version. A full copy of the release notes for this version may be found on the UnboundID website, but many of the improvements are related to connection pooling, load balancing, and failover, but there are other additions and a number of bug fixes also included in this release. Some of the most notable changes include:

  • Added a new fewest connections server set. If used to create a connection pool in which connections span multiple servers, the pool will try to send each newly-created connection to the server with the fewest number of active connections already open by that server set.

  • Updated the LDAPConnectionPool class to make it possible to specify an alternate maximum connection age that should be used for connections created to replace a defunct connection. In the event that a directory server goes down and pooled connections are shifted to other servers, this can help connections fail back more quickly.

  • Updated the failover server set to make it possible to specify an alternate maximum connection age for pooled connections that are established to a server other than the most-preferred server. This can help ensure that failover connections are able to fail back more quickly when the most-preferred server becomes available again.

  • Added a new version of the LDAPConnectionPool.getConnection method that can be used to request a connection to a specific server (based on address and port), if such a connection is readily available.

  • Added a new LDAPConnectionPool.discardConnection method that can be used to close a connection that had been checked out from the pool without creating a new connection in its place. This can be used to reduce the size of the pool if desired.

  • Added a new LDAPConnection.getLastCommunicationTime method that can be used to determine the time that the connection was last used to send a request to or read a response from the directory server, and by extension, the length of time that connection has been idle.

  • Updated the connection pool so that by default, connections which have reached their maximum age will only be closed and replaced by the background health check thread. Previously, the LDAP SDK would also check the connection age when a connection was released back to the pool (and this option is still available if desired), which could cause excess load against the directory server as a result of a number of connections being closed and re-established concurrently. Further, checking the maximum connection age at the time the connection is released back to the pool could have an adverse impact on the perceived response time for an operation because in some cases the LDAP SDK could close and re-establish the connection before the result of the previous operation was made available to the caller.

  • Updated the LDIF writer to add the ability to write the version header at the top of an LDIF file, to ensure that modify change records include a trailing dash after the last change in accordance with the LDIF specification, and to fix a bug that could cause it to behave incorrectly when configured with an LDIF writer entry translator that created a new entry as opposed to updating the entry that was provided to it.

  • Dramatically improved examples included in the Javadoc documentation. All of these examples now have unit test coverage to ensure that the code is valid, and many of the examples now reflect a more real-world usage.

  • Improved the quality of error messages that may be returned for operations that fail as a result of a client-side timeout, or for certain kinds of SASL authentication failures. Also improved the ability to perform low-level debugging for responses received on connections operating in synchronous mode.

  • Updated the in-memory directory server to support enforcing a maximum size limit for searches.

  • Added a couple of example tools that can be used to find supposedly-unique attribute values which appear in multiple entries, or to find entries with DN references to other entries that don't exist.

  • Made a number of improvements around the ability to establish SSL-based connections, or to secure existing insecure connections via StartTLS. Improvements include making it possible to specify the default SSL protocol via a system property so that no code change may be required to set a different default protocol, allowing the ability to define a timeout for StartTLS processing as part of the process for establishing a StartTLS-protected connection.

  • Fixed a bug that could cause the LDAP SDK to enter an infinite loop when attempting to read data from a malformed intermediate response.

  • Fixed a bug that could cause problems in handling the string representation of a search filter that contained non-UTF-8 data.