Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
nsLDAPService Class Reference

#include <nsLDAPService.h>

Inheritance diagram for nsLDAPService:
Inheritance graph
[legend]
Collaboration diagram for nsLDAPService:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSILDAPSERVICE
NS_DECL_NSILDAPMESSAGELISTENER 
nsLDAPService ()
virtual ~nsLDAPService ()
nsresult Init ()
void addServer (in nsILDAPServer aServer)
 Add a (possibly) new LDAP server entry to the service.
void deleteServer (in wstring aKey)
 Mark an LDAP server, in the Service, as a candidate for deletion.
nsILDAPServer getServer (in wstring aKey)
 Get the nsILDAPServer object for the specified server entry in the service.
void requestConnection (in wstring aKey, in nsILDAPMessageListener aListener)
 Request a connection from the service, asynchronously.
nsILDAPConnection getConnection (in wstring aKey)
 This is the nsLDAPConnection object related to this server.
void releaseConnection (in wstring aKey)
 Release the lease on a (cached) LDAP connection, making it a potential candidate for disconnection.
void reconnectConnection (in wstring aKey, in nsILDAPMessageListener aListener)
 If we detect that a connection is broken (server disconnected us, or any other problem with the link), we need to try to reestablish the connection.
AUTF8String createFilter (in unsigned long aMaxSize, in AUTF8String aPattern, in AUTF8String aPrefix, in AUTF8String aSuffix, in AUTF8String aAttr, in AUTF8String aValue)
 Generates and returns an LDAP search filter by substituting aValue, aAttr, aPrefix, and aSuffix into aPattern.
void onLDAPMessage (in nsILDAPMessage aMessage)
 Messages received are passed back via this function.
void onLDAPInit (in nsILDAPConnection aConn, in nsresult aStatus)
 Notify the listener that the Init has completed, passing in the results from the connection initialization.

Protected Member Functions

nsresult EstablishConnection (nsLDAPServiceEntry *, nsILDAPMessageListener *)
char * NextToken (nsReadingIterator< char > &aIter, nsReadingIterator< char > &aIterEnd)
PRUint32 CountTokens (nsReadingIterator< char > aIter, nsReadingIterator< char > aIterEnd)

Protected Attributes

PRLockmLock
nsHashtable * mServers
nsHashtable * mConnections

Detailed Description

Definition at line 112 of file nsLDAPService.h.


Constructor & Destructor Documentation

NS_DECL_ISUPPORTS NS_DECL_NSILDAPSERVICE NS_DECL_NSILDAPMESSAGELISTENER nsLDAPService::nsLDAPService ( )

Definition at line 236 of file nsLDAPService.cpp.

{
    // Delete the hash table holding the entries
    if (mServers) {
        delete mServers;
    }

    // Delete the hash holding the "reverse" lookups from conn to server
    if (mConnections) {
        delete mConnections;
    }

    // Delete the lock object
    if (mLock) {
        PR_DestroyLock(mLock);
    }
}

Here is the call graph for this function:


Member Function Documentation

void nsILDAPService::addServer ( in nsILDAPServer  aServer) [inherited]

Add a (possibly) new LDAP server entry to the service.

A server entry holds information about the host, port and other components of the LDAP URL, as well as information used for binding a connection to the LDAP server.

An LDAP Server entry (nsILDAPServer) contains the URL, user credentials, and other information related to the actual server itself. It is used for connecting, binding, rebinding, setting timeouts and so forth.

Parameters:
aServeran nsILDAPServer object
Exceptions:
NS_ERROR_FAILUREthe server has already been added to the service
NS_ERROR_NULL_POINTERNULL pointer
NS_ERROR_OUT_OF_MEMORYran out of memory
PRUint32 nsLDAPService::CountTokens ( nsReadingIterator< char >  aIter,
nsReadingIterator< char >  aIterEnd 
) [protected]

Definition at line 967 of file nsLDAPService.cpp.

{
    PRUint32 count(0);

    // keep iterating through the string until we hit the end
    //
    while (aIter != aIterEnd) {
    
        // move past any leading spaces
        //
        while (aIter != aIterEnd &&
               ldap_utf8isspace(NS_CONST_CAST(char *, aIter.get()))){
            ++aIter;
        }

        // move past all chars in this token
        //
        while (aIter != aIterEnd) {

            if (ldap_utf8isspace(NS_CONST_CAST(char *, aIter.get()))) {
                ++count;    // token finished; increment the count
                ++aIter;    // move past the space
                break;
            }

            ++aIter; // move to next char

            // if we've hit the end of this token and the end of this 
            // iterator simultaneous, be sure to bump the count, since we're
            // never gonna hit the IsAsciiSpace where it's normally done.
            //
            if (aIter == aIterEnd) {
                ++count;
            }

        }
    }

    return count;
}

Here is the call graph for this function:

AUTF8String nsILDAPService::createFilter ( in unsigned long  aMaxSize,
in AUTF8String  aPattern,
in AUTF8String  aPrefix,
in AUTF8String  aSuffix,
in AUTF8String  aAttr,
in AUTF8String  aValue 
) [inherited]

Generates and returns an LDAP search filter by substituting aValue, aAttr, aPrefix, and aSuffix into aPattern.

The only good documentation I'm aware of for this function is at http://docs.iplanet.com/docs/manuals/dirsdk/csdk41/html/filter.htm and http://docs.iplanet.com/docs/manuals/dirsdk/csdk41/html/function.htm#17835 Unfortunately, this does not currently seem to be available under any open source license, so I can't include that documentation here in the doxygen comments.

Parameters:
aMaxSizemaximum size (in char) of string to be created and returned (including final \0)
aPatternpattern to be used for the filter
aPrefixprefix to prepend to the filter
aSuffixsuffix to be appended to the filer
aAttrreplacement for a in the pattern
aValuereplacement for v in the pattern
Exceptions:
NS_ERROR_INVALID_ARGinvalid parameter passed in
NS_ERROR_OUT_OF_MEMORYallocation failed
NS_ERROR_NOT_AVAILABLEfilter longer than maxsiz chars
NS_ERROR_UNEXPECTEDldap_create_filter returned unexpected error code
void nsILDAPService::deleteServer ( in wstring  aKey) [inherited]

Mark an LDAP server, in the Service, as a candidate for deletion.

If there are still leases ("users") of this server, the operation fails.

Parameters:
aKeyunique key identifying the server entry
Exceptions:
NS_ERROR_FAILUREeither the server doesn't exist, or there are still leases oustanding

Definition at line 703 of file nsLDAPService.cpp.

{
    nsCOMPtr<nsILDAPOperation> operation;
    nsCOMPtr<nsILDAPServer> server;
    nsCOMPtr<nsILDAPURL> url;
    nsCOMPtr<nsILDAPConnection> conn, conn2;
    nsCOMPtr<nsILDAPMessage> message;
    nsCAutoString host;
    nsCAutoString binddn;
    nsCAutoString password;
    PRInt32 port;
    PRUint32 options;
    PRUint32 protocolVersion;
    nsresult rv;

    server = aEntry->GetServer();
    if (!server) {
        return NS_ERROR_FAILURE;
    }

    // Get username, password, and protocol version from the server entry.
    //
    rv = server->GetBinddn(binddn);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }
    rv = server->GetPassword(password);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }
    rv = server->GetProtocolVersion(&protocolVersion);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }

    // Get the host and port out of the URL, which is in the server entry.
    //
    rv = server->GetUrl(getter_AddRefs(url));
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }
    rv = url->GetAsciiHost(host);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }
    rv = url->GetPort(&port);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }

    rv = url->GetOptions(&options);
    if (NS_FAILED(rv)) {
      return NS_ERROR_FAILURE;
    }
    // Create a new connection for this server.
    //
    conn = do_CreateInstance(kLDAPConnectionCID, &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPService::EstablishConnection(): could not create "
                 "@mozilla.org/network/ldap-connection;1");
        return NS_ERROR_FAILURE;
    }

    // Here we need to provide the binddn, see bug #75990
    //
    rv = conn->Init(host.get(), port, 
                    (options & nsILDAPURL::OPT_SECURE) ? PR_TRUE : PR_FALSE, 
                    binddn, this, nsnull, protocolVersion);
    if (NS_FAILED(rv)) {
        switch (rv) {
        // Only pass along errors we are aware of
        //
        case NS_ERROR_OUT_OF_MEMORY:
        case NS_ERROR_NOT_AVAILABLE:
        case NS_ERROR_FAILURE:
            return rv;

        case NS_ERROR_ILLEGAL_VALUE:
        default:
            return NS_ERROR_UNEXPECTED;
        }
    }

    // Try to detect a collision, i.e. someone established a connection
    // just before we did. If so, we drop ours. This code is somewhat
    // similar to what happens in RequestConnection(), i.e. we try to
    // call the listener directly if possible, and if not, push it on
    // the stack of pending requests.
    //
    {
        nsAutoLock lock(mLock);

        conn2 = aEntry->GetConnection();
        message = aEntry->GetMessage();
    }

    if (conn2) {
        // Drop the new connection, we can't use it.
        //
        conn = 0;
        if (message) {
            aListener->OnLDAPMessage(message);
            return NS_OK;
        }

        {
            nsAutoLock lock(mLock);

            if (!aEntry->PushListener(NS_STATIC_CAST(nsILDAPMessageListener *,
                                                     aListener))) {
                return NS_ERROR_FAILURE;
            }
        }

        return NS_OK;
    }

    // We made the connection, lets store it to the server entry,
    // and also update the reverse lookup tables (for finding the
    // server entry related to a particular connection).
    //
    {
        nsVoidKey connKey(NS_STATIC_CAST(nsILDAPConnection *, conn));
        nsAutoLock lock(mLock);

        aEntry->SetConnection(conn);
        mConnections->Put(&connKey, aEntry);
    }

    // Setup the bind() operation.
    //
    operation = do_CreateInstance(kLDAPOperationCID, &rv);
    if (NS_FAILED(rv)) {
        return NS_ERROR_FAILURE;
    }

    rv = operation->Init(conn, this, nsnull);
    if (NS_FAILED(rv)) {
        return NS_ERROR_UNEXPECTED; // this should never happen
    }

    // Start a bind operation 
    //
    // Here we need to support the password, see bug #75990
    // 
    rv = operation->SimpleBind(password);
    if (NS_FAILED(rv)) {
        switch (rv) {
        // Only pass along errors we are aware of
        //
        case NS_ERROR_LDAP_ENCODING_ERROR:
        case NS_ERROR_FAILURE:
        case NS_ERROR_OUT_OF_MEMORY:
            return rv;

        default:
            return NS_ERROR_UNEXPECTED;
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

nsILDAPConnection nsILDAPService::getConnection ( in wstring  aKey) [inherited]

This is the nsLDAPConnection object related to this server.

This does increase the lease counter on the object, so you have to call the releaseConnection() method to return it. It is important that you do this in matching pairs, and that you do not keep any dangling references to an object around after you have called the releaseConnection() method.

Parameters:
aKeyunique key identifying the server entry
Exceptions:
NS_ERROR_FAILUREthere is no server registered in the service with this key
NS_ERROR_NULL_POINTERNULL pointer
nsILDAPServer nsILDAPService::getServer ( in wstring  aKey) [inherited]

Get the nsILDAPServer object for the specified server entry in the service.

Parameters:
aKeyunique key identifying the server entry
Exceptions:
NS_ERROR_FAILUREthere is no server registered in the service with this key
NS_ERROR_NULL_POINTERNULL pointer

Definition at line 256 of file nsLDAPService.cpp.

{
    if (!mLock) {
        mLock = PR_NewLock();
        if (!mLock) {
            NS_ERROR("nsLDAPService::Init: out of memory ");
            return NS_ERROR_OUT_OF_MEMORY;
        }
    }

    if (!mServers) {
        mServers = new nsHashtable(16, PR_FALSE);
        if (!mServers) {
            NS_ERROR("nsLDAPService::Init: out of memory ");
            return NS_ERROR_OUT_OF_MEMORY;
        }
    }

    if (!mConnections) {
        mConnections = new nsHashtable(16, PR_FALSE);
        if (!mConnections) {
            NS_ERROR("nsLDAPService::Init: out of memory ");
            return NS_ERROR_OUT_OF_MEMORY;
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

char * nsLDAPService::NextToken ( nsReadingIterator< char > &  aIter,
nsReadingIterator< char > &  aIterEnd 
) [protected]

Definition at line 1012 of file nsLDAPService.cpp.

{
    // move past any leading whitespace
    //
    while (aIter != aIterEnd &&
           ldap_utf8isspace(NS_CONST_CAST(char *, aIter.get()))) {
        ++aIter;
    }

    nsACString::const_iterator start(aIter);

    // copy the token into our local variable
    //
    while (aIter != aIterEnd &&
           !ldap_utf8isspace(NS_CONST_CAST(char *, aIter.get()))) {
        ++aIter;
    }

    return ToNewCString(Substring(start, aIter));
}

Here is the call graph for this function:

Notify the listener that the Init has completed, passing in the results from the connection initialization.

The Reason for this is to allow us to do asynchronous DNS lookups, preresolving hostnames.

  • aConn The LDAP connection in question
  • aStatus The result from the LDAP connection init

Messages received are passed back via this function.

  • aMessage The message that was returned, NULL if none was.

XXX semantics of NULL?

void nsILDAPService::reconnectConnection ( in wstring  aKey,
in nsILDAPMessageListener  aListener 
) [inherited]

If we detect that a connection is broken (server disconnected us, or any other problem with the link), we need to try to reestablish the connection.

This is very similar to requestConnection(), except you use this when detecting an error with a connection that is being cached.

Parameters:
aKeyunique key identifying the server entry
aMessageListenerthe listener object, which we will call when the LDAP bind message is available
Exceptions:
NS_ERROR_FAILUREthere is no server registered in the service with this key, or we were unable to get a connection properly to the server
NS_ERROR_NOT_AVAILABLEcouldn't create connection thread
NS_ERROR_OUT_OF_MEMORYran out of memory
NS_ERROR_UNEXPECTEDunknown or unexpected error...
void nsILDAPService::releaseConnection ( in wstring  aKey) [inherited]

Release the lease on a (cached) LDAP connection, making it a potential candidate for disconnection.

Note that this will not delete the actual LDAP server entry in the service, it's still registered and can be used in future calls to requestConnection().

This API might be deprecated in the future, once we figure out how to use weak references to support our special needs for reference counting. For the time being, it is vital that you call this function when you're done with a Connection, and that you do not keep any copies of the Connection object lingering around.

Parameters:
aKeyunique key identifying the server entry
Exceptions:
NS_ERROR_FAILUREthere is no server registered in the service with this key
NS_ERROR_OUT_OF_MEMORYran out of memory
void nsILDAPService::requestConnection ( in wstring  aKey,
in nsILDAPMessageListener  aListener 
) [inherited]

Request a connection from the service, asynchronously.

If there is one "cached" already, we will actually call the callback function before returning from this function. This might be considered a bug, but for now be aware of this (see Bugzilla bug #75989).

Calling this method does not increment the leases on this connection, you'll have to use the getConnection() method to actually get the connection itself (presumably from the callback/listener object). The listener needs to implement nsILDAPMessageListener, providing the OnLDAPMessage() method.

Parameters:
aKeyunique key identifying the server entry
aMessageListenerthe listener object, which we will call when the LDAP bind message is available
Exceptions:
NS_ERROR_FAILUREthere is no server registered in the service with this key, or we were unable to get a connection properly to the server
NS_ERROR_NOT_AVAILABLEcouldn't create connection thread
NS_ERROR_OUT_OF_MEMORYran out of memory
NS_ERROR_UNEXPECTEDunknown or unexpected error...

Member Data Documentation

nsHashtable* nsLDAPService::mConnections [protected]

Definition at line 148 of file nsLDAPService.h.

Definition at line 146 of file nsLDAPService.h.

nsHashtable* nsLDAPService::mServers [protected]

Definition at line 147 of file nsLDAPService.h.


The documentation for this class was generated from the following files: