cn=Directory Manager
All about Directory Server
All | Personal | Sun

20060630 Friday June 30, 2006

Working with LDAP Controls

The LDAP specification defines standard behavior for all of the core types of operations that can be performed. However, there are cases in which you want the server to deviate from the default behavior, or perhaps you want it to provide additional information back to the client. This is where controls come in.

LDAP controls have three components:
  • The control type, which is expressed as an OID. This identifies which particular control is involved. This must always be included.

  • The criticality, which is a Boolean value. This indicates whether the control should be considered a critical part of the operation processing. If a control is marked critical and the server does not understand that particular control or cannot perform the associated processing for some reason, then the request containing the control will be rejected. If a control is not marked critical and the server can't process it, then it will continue processing the operation as if the control had not been included. If no criticality is provided, then it is assumed that the control is not critical.

  • The value, which is an octet string (and can therefore basically hold any kind of information). This may or may not be present, depending on the type of control, but if it is present then the encoding for the value will be specific to that type of control.

Technically, controls are all optional. It's not an absolute requirement for an LDAP directory server to support any controls at all, although most if not all do. However, the set of controls that different servers support does vary from one to another. If that's the case, then how is a client supposed to know whether the server it's talking to supports a given control? It can use the supportedControl attribute of the root DSE. In Directory Server 5.2 Patch 4, this might look like:
$ ldapsearch -h ldap.example.com -p 389 -b '' -s base '(objectClass=*)' supportedControl
version: 1
dn:
supportedControl: 1.2.840.113556.1.4.473
supportedControl: 1.3.6.1.4.1.1466.29539.12
supportedControl: 1.3.6.1.4.1.42.2.27.9.5.2
supportedControl: 1.3.6.1.4.1.42.2.27.9.5.6
supportedControl: 1.3.6.1.4.1.42.2.27.9.5.8
supportedControl: 2.16.840.1.113730.3.4.2
supportedControl: 2.16.840.1.113730.3.4.3
supportedControl: 2.16.840.1.113730.3.4.4
supportedControl: 2.16.840.1.113730.3.4.5
supportedControl: 2.16.840.1.113730.3.4.9
supportedControl: 2.16.840.1.113730.3.4.12
supportedControl: 2.16.840.1.113730.3.4.13
supportedControl: 2.16.840.1.113730.3.4.14
supportedControl: 2.16.840.1.113730.3.4.15
supportedControl: 2.16.840.1.113730.3.4.16
supportedControl: 2.16.840.1.113730.3.4.17
supportedControl: 2.16.840.1.113730.3.4.18
supportedControl: 2.16.840.1.113730.3.4.19

The controls that correspond to these OIDs are as follows:
  • 1.2.840.113556.1.4.473 -- This is the server-side sort control as defined in RFC 2891.

  • 1.3.6.1.4.1.1466.29539.12 -- This is a chaining loop-detect control, which is used to help ensure that a misconfigured chaining configuration doesn't create an infinite loop.

  • 1.3.6.1.4.1.42.2.27.9.5.2 -- This is the GetEffectiveRights control, which may be used to determine what operations a given user may perform on a specified entry. See the Directory Server documentation for more information on this feature.

  • 1.3.6.1.4.1.42.2.27.9.5.6 -- This is intended only for internal use within the Directory Server.

  • 1.3.6.1.4.1.42.2.27.9.5.8 -- This is a new "account usable" control that may be used to determine information about the state of a user account (e.g., whether it the password is expired or in a "force change on reset" mode, if the account is disabled, or locked due to failed attempts). I don't believe that this is officially documented anywhere yet (it will be included in the upcoming Directory Server 6 documentation), but it is used by the Solaris Secure LDAP Client implementation and perhaps a crafty individual could find enough information somewhere to help them figure out how to use it.

  • 2.16.840.1.113730.3.4.2 -- This is the Manage DSA IT control, which can be used to request that the Directory Server treat smart referrals like regular entries. This control is described in RFC 3296.

  • 2.16.840.1.113730.3.4.3 -- This is the persistent search control, which can be used to request that the server return information about changes to entries that match a given criteria. This was defined in an IETF draft (draft-ietf-ldapext-psearch) that expired quite a while ago, but an Internet search should help you find a copy.

  • 2.16.840.1.113730.3.4.4 -- This is the Netscape password expired control, which may be included in a bind response from the server to indicate that the bind failed because the user's password is expired.

  • 2.16.840.1.113730.3.4.5 -- This is the Netscape password expiring control, which may be included in a bind response from the server to indicate that the user's password is about to expire.

  • 2.16.840.1.113730.3.4.9 -- This is the Virtual List View request control, which can be used to return arbitrary subsets of the entries matching a given search request. It is most commonly used to page backward and forward through large sets of results, but there are a number of other interesting uses as well. This was defined in a now-expired IETF draft (draft-ietf-ldapext-ldapv3-vlv), but it's not too hard to find this specification.

  • 2.16.840.1.113730.3.4.12 -- This is the proxied authorization V1 request control, which can be used to request that the Directory Server procss a request under the authority of one user while authenticated as another. This was originally defined in an IETF draft, although it is a little harder to find this one because the draft changed midway through into describing version 2 of the control (I believe that the last revision referencing version 1 of the control was draft-weltman-ldapv3-proxy-04). Wherever possible, you should use version 2 of the control instead of version 1.

  • 2.16.840.1.113730.3.4.13 -- This is intended only for internal use within the Directory Server.

  • 2.16.840.1.113730.3.4.14 -- This is the "search on a specific backend" control, which is primarily intended for internal use.

  • 2.16.840.1.113730.3.4.15 -- This is the authorization identity request control, which may be included in a bind request to request that the server provide the authorization ID of the authenticated user in the bind response. This control is described in RFC 3829.

  • 2.16.840.1.113730.3.4.16 -- This is the authorization identity response control, which is also described in RFC 3829.

  • 2.16.840.1.113730.3.4.17 -- This is the "real attributes only" control, which can be used to request that the server not include any virtual attributes (e.g., those generated by the Class of Service feature) in entries that are returned.

  • 2.16.840.1.113730.3.4.18 -- This is the proxied authorization version 2 control, which is defined in RFC 4370. It should be used instead of the older version 1 control where possible.

  • 2.16.840.1.113730.3.4.19 -- This is the "virtual attributes only" control, which can be used to request that the server include only virtual attributes in entries that are returned.

We'll be adding support for additional controls in future versions of the server, so stay tuned.

Posted by cn_equals_directory_manager ( Jun 30 2006, 10:42:22 AM CDT ) Permalink

20060623 Friday June 23, 2006

The SSHA Password Storage Scheme

In an earlier post I discussed the various mechanisms that we have in place for protecting passwords in the Directory Server. One of the forms of protection that we provide comes in the form of password storage schemes, and the default and most secure storage scheme currently included is the SSHA scheme. This is a salted version of the SHA-1 message digest algorithm, and it provides a level of protection against dictionary attacks.

One-way message digest algorithms like SHA-1 and MD5 are intentionally designed so that it's not possible to determine the original cleartext value from the hash value. However, they are also designed so that the same cleartext always hashes to exactly the same digest. Therefore, if I know that the cleartext "password" always generates a base64-encoded SHA-1 hash of "W6ph5Mm5Pz8GgiULbPgzG37mj9g=", then every time I see that encoded value, I know that the cleartext value was "password". If I create a dictionary of pre-hashed values that maps to them to the cleartext used to generate the hashes, I can use that to help me quickly break any commonly-used passwords.

The introduction of a salt into the encoding process is enough to render precomputed dictionaries useless. It works by adding a random element to the digest process so that a given cleartext value does not always generate the same encoded value. If I use SSHA to encode the cleartext "password" five times, then I wil get five different encoded values. In fact, because we use a 64-bit salt there are 18,446,744,073,709,551,616 different ways of encoding the same clear-text value. This makes creating a dictionary completely infeasible because of the sheer volume that would be required to hold even all encodings for a single value.

I've previously stated that there is no reason for a client to know how passwords are encoded in the server, and I stick by that. Any client that attempts to verify passwords externally is broken, since it can't abide by the configured password policy, and because it will stop working if the storage scheme is changed in the future. Similarly, allowing applications to pre-encode passwords before sending them to the server can also bypass password policy restrictions. Nevertheless, we frequently find that people are curious as to exactly how SSHA works, so I'll describe it here for informational purpopses only.

The algorithm that we use is actually very simple:
  1. Generate eight bytes of random data to use as the salt
  2. Append the salt bytes to the bytes that make up the cleartext password
  3. Generate the SHA-1 digest of the password+salt
  4. Append the salt bytes to the SHA-1 digest
  5. Base64-encode the resulting digest+salt bytes and append that to the string "{SSHA}"

When a user attempts to bind to the Directory Server, the server validates the clear-text password provided by the user in the following way:
  1. Get the encoded password from the user's entry
  2. Read the string inside the curly braces and use it to determine which password storage scheme was used to encode the password (in this case, we'll assume it was "SSHA")
  3. Remove the "{SSHA}" prefix and base64-decode the remaining value
  4. Remove the last eight bytes from the decoded value to use as the salt
  5. Append the salt to the clear-text password from the bind request
  6. Generate the SHA-1 digest of the password+salt and compare it against the password+salt portion (i.e., all but the last eight bytes) from the base64-decoded value found in step #4

To better illustrate this process, I've created a very simple Java class that can be used to either encode a clear-text password using SSHA or compare a given clear-text password with an encoded password to determine whether it is valid. It should be self-contained and thoroughly commented, so it may help illustrate the steps outlined above in a more programmatic manner.

Posted by cn_equals_directory_manager ( Jun 23 2006, 12:31:16 PM CDT ) Permalink

20060621 Wednesday June 21, 2006

Protecting Passwords in the Directory Server

In order to perform simple authentication, the Directory Server must store the user's password so that it can be verified while processing the bind request. Because the server is storing so many passwords, that could make it a potential target for people trying to gain unauthorized access to various systems. If you can figure out a user's password, then you can likely impersonate that person in any application that uses LDAP simple authentication to identify users. Therefore, it stands that this is something that needs to be as difficult as possible to achieve.

The first line of defense that the Directory Server offers is in the area of access control. It is a relatively simple matter to ensure that the password will not be accessible to users, and in fact this is the default configuration. If anyone other than an administrator retrieves a user's entry, then the password will not be included in that entry. It's possible to override this, of course, but in general it's not recommended. There should be no reason for clients to need to see this (and any client that authenticates clients by retrieving the password and manually comparing it against what the user provided is fundamentally broken), so this is a good first step.

The second step is to prevent passwords from being exposed to those that might be able to observe the network communication between clients and the Directory Server. Even though most users can't retrieve passwords, the root DN (typically "cn=Directory Manager") and other administrative users may be able to do so, and you'll want to prevent other observers from being able to see that. Further, simple bind requests will always contain the password in the clear, so that should be protected as well. All of this can be achieved through the use of SSL/TLS, or through a related mechanism like IPsec. Most of these mechanisms also include protection against man-in-the-middle attacks, where someone sets up a simple proxy server that can capture passwords as they're being sent to the server.

Preventing access to the passwords over LDAP is very important, but it's not the only method that a malicious user might try to get access to them. The passwords will also be contained on disk in the Directory Server database, as well as in backups and LDIF exports of the data. Therefore, it's critical to make sure that the set of people that have access to the Directory Server systems and data backups is limited only to those that really need it.

Fortunately, even if someone does have access to see passwords as they are stored in the Directory Server, there is still another level of protection that will create some difficulty for an attacker. In most cases, the passwords are not stored in the clear, but rather are encoded using password storage schemes. A password storage scheme provides a way to represent a password that can be used by the Directory Server to determine if a password provided in a bind request is correct but that makes it very difficult to tell what the actual password is. The storage schemes provided by the server out of the box include:
  • CLEAR -- This simply stores the password in the clear. It's the least secure, but it may be required for certain types of authentication like the DIGEST-MD5 SASL mechanism that require access to the cleartext password. Unless you're using a mechanism that requires it, you should avoid the use of clear-text passwords.

  • CRYPT -- This uses the UNIX crypt algorithm (basically a simple form of one-way hashing using DES). This is primarily provided for compatibility with some of those broken applications that either retrieve the password to verify it externally, or pre-encode the password before storing it in the server. It's not very secure, so you shouldn't use it unless you absolutely have to.

  • SHA -- This uses the SHA-1 message digest algorithm defined in FIPS 180-1 to store a one-way digest of the password. This is a secure mechanism, and it is computationally infeasible for someone to determine the clear-text password based on its SHA-1 hash. However, it does not use any salting so unless unsalted SHA-1 is required you should use SSHA instead.

  • SSHA -- This uses a salted version of the SHA-1 digest to store passwords. This is generally more secure than unsalted SHA-1 because it adds a level of protection against dictionary attacks. I'll go into the specifics of our SSHA implementation in another post, but for now you can just know that it's the strongest storage scheme that we currently offer and unless you have a specific reason for using something else you should use it. SSHA is the default mechanism used by our server, so unless you've updated your password policy to use a different storage scheme, you're already using it.

Note that it is possible to add support for new password storage schemes to the server (as documented in the Plug-In Developer's Guide), so if none of our default schemes are appropriate for your deployment you can add support for your own without too much difficulty. And I should point out that we will be adding support for additional storage schemes in the future so you will have more choices available that may be more appropriate in certain cases.

With all of these levels of protection for user passwords, about the only thing that an attacker can try (other than social engineering or looking for post-it notes with the password written on it) is brute force. At this point, it all comes down to the strength of the user's password. This is primarily a function of the character set used for the password and the number of characters in the password. For example, if we know that the password is comprised of six lowercase alphabetic characters, then there can only be 308,915,776 possible values. My laptop can do about 3 million of these hashes per second, so that's only 100 seconds to run through the entire set of possible values. On the other hand, if a password is 10 characters long and can use the full set of 95 printable ASCII characters then there are 59,873,693,923,837,890,625 possible values and it would take my laptop over 630,000 years to work thorugh all of them. Even a massive compute grid isn't going to be able to knock that down to anything that's even close to a reasonable length of time, so not even brute force is a feasilbe attack vector for something like that.

Ultimately, this means that password security is really an issue of the strength of the passwords. Our server currently offers the ability to enforce a minimum length and provide some other basic checks like ensuring that the password doesn't match the values of other attributes in the user's entry. The upcoming Directory Server 6 release will include a number of other checks that can be enforced (you may be able to get this as a plugin for a 5.x server through our professional services engineering) like ensuring passwords use different classes of characters (e.g., at least some number of lowercase letters, uppercase letters, numeric digits, and other symbols) and dictionary checks, and we've got even bigger plans for releases after that. If you've got to use passwords for authentication, then we want to help you keep them as secure as possible.

Posted by cn_equals_directory_manager ( Jun 21 2006, 08:17:01 AM CDT ) Permalink Comments [3]

20060616 Friday June 16, 2006

LDAP Authentication Mechanisms

One of the most common tasks that the Directory Server is given is to serve as the repository for authenticating users. Traditionally, this is accomplished by binding to the server using simple authentication, but there are other options that may have their own advantages and disadvantages. These options come in the form of SASL mechanisms, where SASL is the Simple Authentication Security Layer defined in RFC 2222 and recently updated in RFC 4422. Many people may not be familiar with all of these methods, so I'll briefly describe them here.

Note that this post isn't going to go into a lot of detail about how to configure the server or clients to perform these types of authentication. The Directory Server Administration Guide, and in particular Chapter 11: Managing Authentication and Encryption provides instructions for doing this.

LDAP simple authentication is aptly-named because it is a very straightforward mechanism. A user binding with simple authentication needs only to provide their DN and password. This is the most widely supported LDAP authentication method, so chances are pretty good that if your application supports authenticating against a Directory Server then it can use simple authentication. However, there are a couple of disadvantages to using simple authentication. The first is that in order to authenticate the client must know the users's DN, which is not necessarily something that the end user is likely to know. However, this is generally overcome by first performing a search to find the user's entry (e.g., based on a uid or e-mail address), and then take the DN from that user entry to use in the simple authentication. The second disadvantage is that simple authentication does nothing to protect the user's password as it is transmitted over the network, so anyone that can listen in can see the password in the clear. This can be overcome by encrypting the communication with the server (e.g., using SSL/TLS to perform the encryption at the client-server level, or using IPsec to achieve it at a host or network level).

Even though it is a relatively straightforward process to encrypt the communication between the client and the server to protect the credentials used for simple authentication, this does incur a cost for the entire set of communication because it is not possible to encrypt only the bind request (it is possible to use the StartTLS extended operation to encrypt only a portion of the interaction between the client and the server, but it also requires that any existing authentication be disregarded when transitioning from secure to insecure communication). In some cases, encrypting the entire session between the client and the server may add an undesirable amount of overhead if the password is the only thing that would need to be protected. In this case, an alternative that you could consider would be the use of SASL authentication with the DIGEST-MD5 mechanism.

The DIGEST-MD5 mechanism is a password-based authentication method whose primary benefit is that it doesn't expose the bind password to anyone that might happen to be listening in on the network communication between the client and the server. It is able to accomplish this because the password itself is never transferred, but rather just information that proves the client does know the user's real password. It is a little more complicated than the simple authentication process because it requires a multi-stage bind (basically, the client and server both come up with some random data and then use that in combination with the user's password to generate an MD5 hash), but ultimately the password is never exposed in the clear, and the mechanism is relatively secure against replay and man-in-the-middle attacks. It also has the benefit of being able to authenticate using an authorization ID (which can specify either a user ID or a full DN), which means that the client doesn't necessarily have to do a search first in order to get the user's DN. The primary downside of using the DIGEST-MD5 authentication mechanism is that it requires the Directory Server to know the clear-text password for the user. For our current server, this means that the values must be stored in the clear (i.e., using the "CLEAR" scheme). This is an unacceptable proposition in most cases because of the dangers associated with keeping the passwords in the clear, although we will likely eliminate many of these concerns in the future by adding password storage schemes based on reversible encryption.

While passwords are certainly very commonly used in LDAP authentication, they are certainly not the only form of credentials that are available. In particular, our Directory Server supports two other SASL mechanisms that don't directly involve passwords: EXTERNAL and GSSAPI. The EXTERNAL mechanism tells the Directory Server that the user wants to authenticate based on some other identifying information that may be available. In our Directory Server, this currently is available only for client connections that have been established using SSL where the client has provided its own certificate to the server (i.e., SSL client authentication). The Directory Server can use the information in that certificate to map it to a user's entry and can accept that as authentication. Since this is based on relatively strong cryptographic methods, it can be significantly more secure than using passwords, but it is also more complicated to manage because each user must have their own certificate and the Directory Server must have enough information available to determine whether to trust that certificate. On a large scale, this generally involves a PKI deployment and may also require storing public keys in user entries for use in the validation process, and this can be a cumbersome process to set up and manage.

The SASL GSSAPI mechanism allows a user to authenticate to the Directory Server through Kerberos V. For cases in which Kerberos is already deployed and used as a single sign-on solution for other applications in the environment, this can be a relatively simple way to expand that to include authenticating to the Directory Server. In that case, the server will require its own Kerberos key and must be able to map the client principals to user entries for the authentication process, but it may be an attractive option for environments where Kerberos is already widely deployed.

There are a number of other SASL mechanisms that have been defined, but at present our server only supports EXTERNAL, DIGEST-MD5, and GSSAPI. We are considering adding support for other mechanisms like CRAM-MD5 and PLAIN in future releases, but if there are other mechanisms that you might find useful then that would be helpful for us to know as well.

Posted by cn_equals_directory_manager ( Jun 16 2006, 02:02:12 PM CDT ) Permalink Comments [2]

20060608 Thursday June 08, 2006

Lots of New LDAP RFCs

The RFC editor was busy today. RFCs 4510 through 4533 all deal with LDAP in some way. Several of them came from the ldapbis working group, which provides clarification on the core LDAPv3 specifications so there's not a whole lot of new and groundbreaking stuff. Nevertheless, if you've never read through the official protocol specification, then it's worth checking out. In particular:
  • RFC 4510 -- LDAP: Technical Specification Road Map
  • RFC 4511 -- LDAP: The Protocol
  • RFC 4512 -- LDAP: Directory Information Models
  • RFC 4513 -- LDAP: Authentication Methods and Security Mechanisms
  • RFC 4514 -- LDAP: String Representation of Distinguished Names
  • RFC 4515 -- LDAP: String Representation of Search Filters
  • RFC 4516 -- LDAP: Uniform Resource Locator
  • RFC 4517 -- LDAP: Syntaxes and Matching Rules

In addition to updating the core specifications, there were also some new specifications that made it out of the draft phase. Some of the most interesting of these include:
  • RFC 4525 -- LDAP Modify-Increment Extension
  • RFC 4527 -- LDAP Read Entry Controls
  • RFC 4528 -- LDAP Assertion Control
  • RFC 4529 -- Requesting Attributes by Object Class in LDAP
  • RFC 4530 -- LDAP entryUUID Operational Attribute
  • RFC 4532 -- LDAP "Who am I?" Operation

These have been around in draft form for a while, and we already provide support for the "Who am I?" operation in current releases and others are slated for inclusion in future releases. We're certainly intent in keeping up with the proposals and specifications, and if there are other specifications that you think you would find particularly useful then let us know. We can't make any promises, but it always helps to know what our customers feel are the most important enhancements that we can make.

Posted by cn_equals_directory_manager ( Jun 08 2006, 11:42:51 PM CDT ) Permalink Comments [1]

20060605 Monday June 05, 2006

LDAP Connection Pooling

If you're developing applications to communicate with the Directory Server, you'll want to make your code as efficient as possible to minimize the load on the server and to get the responses as quickly as possible. A couple of weeks ago, I gave a few tips for develping such applications. One of these was the recommendation to use connection pools wherever possible. That's actually a pretty broad topic, and it deserves its own post.

Connection pooling is a very good thing for a few reasons. The biggest benefit that it provides is that it saves the expense of establishing a new connection every time the client wants to issue a request to the server. Just establishing the TCP connection can be pretty expensive, especially when SSL is involved, so avoiding it is a good thing. Using connection pools also helps keep the total number of connections to the server down, since a few connections can be shared by all the end users instead of having a separate connection per concurrent user. The number of concurrent connections really doesn't have much impact on the performance of Sun's Directory Server, but each connection does use a little memory and keeping lots of connections open can consume all of the server's available file descriptors so it can't accept any new connections. Finally, a good connection pooling implementation can make it easier for your application to deal with errors and fail over to another server in the event of a problem, and it can also work to spread the load across multiple servers.

The term "connection pool" can mean different things to different people, and what they envision can have varying degrees of complexity. In its simplest form, a connection pool is simply a set of one or more connections that remain established for an extended period of time and may be accessed by multiple threads in an application (or in some cases, in multiple applications). And even in "more complex" forms, they are still pretty simple and ultimately just boil down to a list of connections. However, I've come up with a set of tips that you might find helpful if you're considering implementing your own pool:
  • If the server supports it, then you should use the proxied authorization control (as defined in RFC 4370) to specify the identity of the user under whose authority the operations should be performed. This control allows you to perform operations as the target user in the directory without actually needing to be bound as that user. This is particularly useful in a connection pool because it prevents you from having to re-bind the connections when they're pulled from the pool. It's also particularly useful if the client authenticated using a mechanism that can't be re-played (e.g., a certificate) or if the authentication was external to the client (e.g., by Access Manager).

  • If you do use the proxied authorization control for your application, then you may need to create two pools: one for bind operations and one for all other types of operations. The proxied authorization control cannot be used for bind operations, so if your application needs to perform binds (e.g., to verify the credentials provided by the user).

  • You must take great care to avoid "leaking" connections. That is, whenever you take a connection out of the pool, you must make sure that it gets returned to the pool when the operation is complete. The primary exception to this may be the case in which the connection is no longer valid (e.g., if you detect that the server is down), but you'll still want to include an option in the pool to indicate that it needs to create a new connection.

  • Even though a connection "pool" can be implemented using a single connection that is shared across multiple application threads (possibly processing multiple requests concurrently for separate threads), it is generally a better idea to use multiple connections where each will be used to process at most one operation at any given time. This will generally result in better performance, and will also provide better isolation to application components in the event of a failure.

  • When using a connection pool, you will want to have a way of detecting failures and deciding what to do about them. If the server returns an error result, then you should interpret the result code to indicate whether it is something that might indicate a problem on the server (e.g., UNAVAILABLE, or BUSY) that might necessitate a failover. You'll also want to set a timeout for the requests that can be used to detect whether the server might be hung or otherwise unavailable (e.g., network or system failure). In most cases, I don't think that health checks are necessary if you can detect and handle failures as they happen, since the periodic health checks will simply generate extra load against the server and you'll need to detect failures as they happen anyway (i.e., there's no guarantee that a problem won't arise immediately after a health check but immediately before a client request).

  • In most cases, you will want to build failover of some kind into the connection pool, but you should use some intelligence when deciding exactly what actions to take. Some things to consider include:
    • Will you implement a circular fail-forward mechanism (i.e., when a failure occurs go to the next server in the list and stay there until the next failure) or will there be a fail-back when the original server is available again?
    • Should you include special support for transient "errors" that aren't really problems, like connections closed due to an idle time limit?
    • Should the application be allowed to use all replicas in the environment, or should it be restricted to a subset of them? If it's allowed to use all of the servers, then it's theoretically possible to take down the entire service if a client triggers a bug in the server or consumes all worker threads with inefficient requests, whereas using different sets of servers for different applications can help ensure that if such a problem does occur that the entire service doesn't become unavailable for all applications.

Traditional connection pool implementations merely provide the basic framework that allows the client to check out and return connections. Many SDKs provide supporf for this type of pooling, but I feel that they are often too lacking in support for things like failure handling, and they often leave too much work to the application developer. I generally prefer to develop my own connection pool implementation, and in the process of doing so push a lot of the common logic into the pool itself. For example, although it is possible to retrieve a connection from the pool, I also include helper methods that make it possible to perform most common operations in the pool itself (where the method will retrieve a connection, perform the request, take care of any necessary error handling, and return the connection to the pool). This simplifies the application and avoids unnecessary duplication of code and makes it easier to ensure that there are no connection leaks or other problems. I'm not aware of any LDAP SDKs that currently provide this capability, but perhaps that's a feature that we can provide at some point in the future. Fortunately, it's not that difficult for you to implement for yourself and I believe that the benefits of doing so greatly outweigh the time and effort invested in it.

Posted by cn_equals_directory_manager ( Jun 05 2006, 08:10:28 AM CDT ) Permalink


Archives
Language
Links
Referrers