зеркало из https://github.com/mozilla/gecko-dev.git
Initial implementation and supporting changes for nsLDAPService (bug 70422). Patch from Leif Hedstrom <leif@netscape.com>, r=dmose@netscape.com, sr=brendan@mozilla.org.
This commit is contained in:
Родитель
a05554f8ba
Коммит
0fedea1b41
|
@ -4,4 +4,5 @@ nsILDAPMessage.idl
|
|||
nsILDAPURL.idl
|
||||
nsILDAPMessageListener.idl
|
||||
nsILDAPErrors.idl
|
||||
nsILDAPServer.idl
|
||||
nsILDAPServer.idl
|
||||
nsILDAPService.idl
|
||||
|
|
|
@ -49,6 +49,7 @@ XPIDLSRCS = \
|
|||
nsILDAPURL.idl \
|
||||
nsILDAPErrors.idl \
|
||||
nsILDAPServer.idl \
|
||||
nsILDAPService.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
|
|
|
@ -32,6 +32,7 @@ XPIDLSRCS= .\nsILDAPConnection.idl \
|
|||
.\nsILDAPMessageListener.idl \
|
||||
.\nsILDAPErrors.idl \
|
||||
.\nsILDAPServer.idl \
|
||||
.\nsILDAPService.idl \
|
||||
!if defined(ENABLE_LDAP_EXPERIMENTAL)
|
||||
!endif
|
||||
$(NULL)
|
||||
|
|
|
@ -76,6 +76,13 @@ interface nsILDAPMessage : nsISupports
|
|||
void getValues(in string attr, out unsigned long count,
|
||||
[retval, array, size_is(count)] out string values);
|
||||
|
||||
/**
|
||||
* The operation this message originated from
|
||||
*
|
||||
* @exception NS_ERROR_NULL_POINTER NULL pointer to getter
|
||||
*/
|
||||
readonly attribute nsILDAPOperation operation;
|
||||
|
||||
/**
|
||||
* The result code (aka lderrno) for this message.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the mozilla.org LDAP XPCOM component.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Leif Hedstrom <leif@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
interface nsILDAPServer;
|
||||
interface nsILDAPConnection;
|
||||
interface nsILDAPMessageListener;
|
||||
|
||||
/**
|
||||
* This interface provides an LDAP connection management service.
|
||||
* It's used to cache already established LDAP connections, as well
|
||||
* as reaping unused connections after a certain time period. This
|
||||
* is done completely asynchronously, using callback functions.
|
||||
*/
|
||||
|
||||
|
||||
[scriptable, uuid(f73cc6c1-2301-484b-94a5-8885bca106d1)]
|
||||
interface nsILDAPService : nsISupports {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param aServer an nsILDAPServer object
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE the server has already been
|
||||
* added to the service
|
||||
* @exception NS_ERROR_NULL_POINTER NULL pointer
|
||||
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
|
||||
*/
|
||||
void addServer(in nsILDAPServer aServer);
|
||||
|
||||
/**
|
||||
* Mark an LDAP server, in the Service, as a candidate for
|
||||
* deletion. If there are still leases ("users") of this server,
|
||||
* the operation fails.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE either the server doesn't
|
||||
* exist, or there are still
|
||||
* leases oustanding
|
||||
*/
|
||||
void deleteServer(in wstring aKey);
|
||||
|
||||
/**
|
||||
* Get the nsILDAPServer object for the specified server entry
|
||||
* in the service.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there is no server registered
|
||||
* in the service with this key
|
||||
* @exception NS_ERROR_NULL_POINTER NULL pointer
|
||||
*/
|
||||
nsILDAPServer getServer(in wstring aKey);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
* @param aMessageListener the listener object, which we will call
|
||||
* when the LDAP bind message is available
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there is no server registered
|
||||
* in the service with this key,
|
||||
* or we were unable to get a
|
||||
* connection properly to the server
|
||||
* @exception NS_ERROR_NOT_AVAILABLE couldn't create connection thread
|
||||
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
|
||||
* @exception NS_ERROR_UNEXPECTED unknown or unexpected error...
|
||||
*/
|
||||
void requestConnection(in wstring aKey,
|
||||
in nsILDAPMessageListener aListener);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there is no server registered
|
||||
* in the service with this key
|
||||
* @exception NS_ERROR_NULL_POINTER NULL pointer
|
||||
*/
|
||||
nsILDAPConnection getConnection(in wstring aKey);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there is no server registered
|
||||
* in the service with this key
|
||||
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
|
||||
*/
|
||||
void releaseConnection(in wstring aKey);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param aKey unique key identifying the server entry
|
||||
* @param aMessageListener the listener object, which we will call
|
||||
* when the LDAP bind message is available
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there is no server registered
|
||||
* in the service with this key,
|
||||
* or we were unable to get a
|
||||
* connection properly to the server
|
||||
* @exception NS_ERROR_NOT_AVAILABLE couldn't create connection thread
|
||||
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
|
||||
* @exception NS_ERROR_UNEXPECTED unknown or unexpected error...
|
||||
*/
|
||||
void reconnectConnection(in wstring aKey,
|
||||
in nsILDAPMessageListener aListener);
|
||||
};
|
|
@ -52,6 +52,7 @@ CPPSRCS = \
|
|||
nsLDAPOperation.cpp \
|
||||
nsLDAPURL.cpp \
|
||||
nsLDAPServer.cpp \
|
||||
nsLDAPService.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
|
@ -60,7 +61,6 @@ DEFINES += -DMOZ_LDAP_XPCOM_EXPERIMENTAL
|
|||
CPPSRCS += \
|
||||
nsLDAPProtocolHandler.cpp \
|
||||
nsLDAPChannel.cpp \
|
||||
nsLDAPService.cpp \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES += mimetype
|
||||
|
@ -74,4 +74,3 @@ CSRCS = \
|
|||
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) -lldap40 -llber40
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ CPP_OBJS = .\$(OBJDIR)\nsLDAPURL.obj \
|
|||
.\$(OBJDIR)\nsLDAPConnection.obj \
|
||||
.\$(OBJDIR)\nsLDAPOperation.obj \
|
||||
.\$(OBJDIR)\nsLDAPServer.obj \
|
||||
.\$(OBJDIR)\nsLDAPService.obj \
|
||||
!if defined(ENABLE_LDAP_EXPERIMENTAL)
|
||||
.\$(OBJDIR)\nsLDAPProtocolHandler.obj \
|
||||
.\$(OBJDIR)\nsLDAPChannel.obj \
|
||||
.\$(OBJDIR)\nsLDAPService.obj \
|
||||
!endif
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ extern "C" int nsLDAPThreadFuncsInit(LDAP *aLDAP);
|
|||
// constructor
|
||||
//
|
||||
nsLDAPConnection::nsLDAPConnection()
|
||||
: mConnectionHandle(0),
|
||||
mPendingOperations(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
@ -77,7 +79,6 @@ nsLDAPConnection::~nsLDAPConnection()
|
|||
if (mPendingOperations) {
|
||||
delete mPendingOperations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsLDAPConnection, nsILDAPConnection,
|
||||
|
@ -573,6 +574,11 @@ nsLDAPConnection::InvokeMessageCallback(LDAPMessage *aMsgHandle,
|
|||
|
||||
operation = getter_AddRefs(NS_STATIC_CAST(nsILDAPOperation *, data));
|
||||
|
||||
// Make sure the mOperation member is set to this operation before
|
||||
// we call the callback.
|
||||
//
|
||||
NS_STATIC_CAST(nsLDAPMessage *, aMsg)->mOperation = operation;
|
||||
|
||||
// get the message listener object (this may be a proxy for a
|
||||
// callback which should happen on another thread)
|
||||
//
|
||||
|
|
|
@ -57,7 +57,6 @@ nsLDAPMessage::nsLDAPMessage()
|
|||
//
|
||||
nsLDAPMessage::~nsLDAPMessage(void)
|
||||
{
|
||||
|
||||
if (mMsgHandle) {
|
||||
int rc = ldap_msgfree(mMsgHandle);
|
||||
|
||||
|
@ -527,6 +526,18 @@ nsLDAPMessage::GetValues(const char *aAttr, PRUint32 *aCount,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// readonly attribute nsILDAPOperation operation;
|
||||
NS_IMETHODIMP nsLDAPMessage::GetOperation(nsILDAPOperation **_retval)
|
||||
{
|
||||
if (!_retval) {
|
||||
NS_ERROR("nsLDAPMessage::GetOperation: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*_retval = mOperation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLDAPMessage::ToUnicode(PRUnichar* *aString)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Dan Mosedale <dmose@mozilla.org>
|
||||
* Leif Hedstrom <leif@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
|
@ -38,11 +39,11 @@
|
|||
#include "nsLDAPOperation.h"
|
||||
#include "nsLDAPMessage.h"
|
||||
#include "nsLDAPServer.h"
|
||||
#include "nsLDAPService.h"
|
||||
|
||||
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
#include "nsLDAPProtocolHandler.h"
|
||||
#include "nsLDAPChannel.h"
|
||||
#include "nsLDAPService.h"
|
||||
#endif
|
||||
|
||||
// use the default constructor
|
||||
|
@ -52,10 +53,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPOperation);
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPMessage);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPURL);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPServer);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPService, Init);
|
||||
|
||||
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPProtocolHandler);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPService, Init);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -73,12 +74,12 @@ static nsModuleComponentInfo components[] =
|
|||
"@mozilla.org/network/ldap-message;1", nsLDAPMessageConstructor },
|
||||
{ "LDAP Server", NS_LDAPSERVER_CID,
|
||||
"@mozilla.org/network/ldap-server;1", nsLDAPServerConstructor },
|
||||
{ "LDAP Service", NS_LDAPSERVICE_CID,
|
||||
"@mozilla.org/network/ldap-service;1", nsLDAPServiceConstructor },
|
||||
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
{ "LDAP Protocol Handler", NS_LDAPPROTOCOLHANDLER_CID,
|
||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ldap",
|
||||
nsLDAPProtocolHandlerConstructor },
|
||||
{ "LDAP Service", NS_LDAPSERVICE_CID,
|
||||
"@mozilla.org/network/ldap-service;1", nsLDAPServiceConstructor },
|
||||
#endif
|
||||
{ "LDAP URL", NS_LDAPURL_CID,
|
||||
"@mozilla.org/network/ldap-url;1", nsLDAPURLConstructor }
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Dan Mosedale <dmose@mozilla.org>
|
||||
* Contributor(s): Leif Hedstrom <leif@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
|
@ -34,10 +34,206 @@
|
|||
|
||||
#include "nsLDAPInternal.h"
|
||||
#include "nsLDAPService.h"
|
||||
#include "nsLDAPConnection.h"
|
||||
#include "nsLDAPOperation.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsILDAPURL.h"
|
||||
#include "nsAutoLock.h"
|
||||
|
||||
|
||||
// Constants for CIDs used here.
|
||||
//
|
||||
static NS_DEFINE_CID(kLDAPConnectionCID, NS_LDAPCONNECTION_CID);
|
||||
static NS_DEFINE_CID(kLDAPOperationCID, NS_LDAPOPERATION_CID);
|
||||
|
||||
// First we provide all the methods for the "local" class
|
||||
// nsLDAPServiceEntry.
|
||||
//
|
||||
|
||||
// constructor
|
||||
//
|
||||
nsLDAPServiceEntry::nsLDAPServiceEntry()
|
||||
: mLeases(0),
|
||||
mDelete(PR_FALSE),
|
||||
mRebinding(PR_FALSE)
|
||||
|
||||
{
|
||||
mTimestamp = LL_Zero();
|
||||
}
|
||||
|
||||
// destructor
|
||||
//
|
||||
nsLDAPServiceEntry::~nsLDAPServiceEntry()
|
||||
{
|
||||
}
|
||||
|
||||
// Init function
|
||||
//
|
||||
PRBool nsLDAPServiceEntry::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mListeners));
|
||||
if (NS_FAILED(rv)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Set/Get the timestamp when this server was last used. We might have
|
||||
// to use an "interval" here instead, see Bug #76887.
|
||||
//
|
||||
PRTime nsLDAPServiceEntry::GetTimestamp()
|
||||
{
|
||||
return mTimestamp;
|
||||
}
|
||||
void nsLDAPServiceEntry::SetTimestamp()
|
||||
{
|
||||
mTimestamp = PR_Now();
|
||||
}
|
||||
|
||||
|
||||
// Increment, decrement and Get the leases. This code might go away
|
||||
// with bug #75954.
|
||||
//
|
||||
void nsLDAPServiceEntry::IncrementLeases()
|
||||
{
|
||||
mLeases++;
|
||||
}
|
||||
PRBool nsLDAPServiceEntry::DecrementLeases()
|
||||
{
|
||||
if (!mLeases) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
mLeases--;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
PRUint32 nsLDAPServiceEntry::GetLeases()
|
||||
{
|
||||
return mLeases;
|
||||
}
|
||||
|
||||
// Get/Set the nsLDAPServer object for this entry.
|
||||
//
|
||||
nsILDAPServer *nsLDAPServiceEntry::GetServer()
|
||||
{
|
||||
nsILDAPServer *server;
|
||||
|
||||
NS_IF_ADDREF(server = mServer);
|
||||
return server;
|
||||
}
|
||||
PRBool nsLDAPServiceEntry::SetServer(nsILDAPServer *aServer)
|
||||
{
|
||||
if (!aServer) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
mServer = aServer;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Get/Set/Clear the nsLDAPConnection object for this entry.
|
||||
//
|
||||
nsILDAPConnection *nsLDAPServiceEntry::GetConnection()
|
||||
{
|
||||
nsILDAPConnection *conn;
|
||||
|
||||
NS_IF_ADDREF(conn = mConnection);
|
||||
return conn;
|
||||
}
|
||||
void nsLDAPServiceEntry::SetConnection(nsILDAPConnection *aConnection)
|
||||
{
|
||||
mConnection = aConnection;
|
||||
}
|
||||
|
||||
// Get/Set the nsLDAPMessage object for this entry (it's a "cache").
|
||||
//
|
||||
nsILDAPMessage *nsLDAPServiceEntry::GetMessage()
|
||||
{
|
||||
nsILDAPMessage *message;
|
||||
|
||||
NS_IF_ADDREF(message = mMessage);
|
||||
return message;
|
||||
}
|
||||
void nsLDAPServiceEntry::SetMessage(nsILDAPMessage *aMessage)
|
||||
{
|
||||
mMessage = aMessage;
|
||||
}
|
||||
|
||||
// Push/Pop pending listeners/callback for this server entry. This is
|
||||
// implemented as a "stack" on top of the nsVoidArrays, since we can
|
||||
// potentially have more than one listener waiting for the connection
|
||||
// to be avilable for consumption.
|
||||
//
|
||||
nsILDAPMessageListener *nsLDAPServiceEntry::PopListener()
|
||||
{
|
||||
nsILDAPMessageListener *listener;
|
||||
PRUint32 count;
|
||||
|
||||
mListeners->Count(&count);
|
||||
if (!count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
listener = NS_STATIC_CAST(nsILDAPMessageListener *,
|
||||
mListeners->ElementAt(0));
|
||||
mListeners->RemoveElementAt(0);
|
||||
|
||||
return listener;
|
||||
}
|
||||
PRBool nsLDAPServiceEntry::PushListener(nsILDAPMessageListener *listener)
|
||||
{
|
||||
PRBool ret;
|
||||
PRUint32 count;
|
||||
|
||||
mListeners->Count(&count);
|
||||
ret = mListeners->InsertElementAt(listener, count);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Mark this server to currently be rebinding. This is to avoid a
|
||||
// race condition where multiple consumers could potentially request
|
||||
// to reconnect the connection.
|
||||
//
|
||||
PRBool nsLDAPServiceEntry::IsRebinding()
|
||||
{
|
||||
return mRebinding;
|
||||
}
|
||||
void nsLDAPServiceEntry::SetRebinding(PRBool aState)
|
||||
{
|
||||
mRebinding = aState;
|
||||
}
|
||||
|
||||
// Mark a service entry for deletion, this is "dead" code right now,
|
||||
// see bug #75966.
|
||||
//
|
||||
PRBool nsLDAPServiceEntry::DeleteEntry()
|
||||
{
|
||||
mDelete = PR_TRUE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
// This is the end of the nsLDAPServiceEntry class
|
||||
|
||||
|
||||
// Here begins the implementation for nsLDAPService
|
||||
//
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsLDAPService,
|
||||
nsILDAPService,
|
||||
nsILDAPMessageListener);
|
||||
|
||||
|
||||
// constructor
|
||||
//
|
||||
nsLDAPService::nsLDAPService()
|
||||
: mLock(0),
|
||||
mServers(0),
|
||||
mConnections(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
@ -46,40 +242,610 @@ nsLDAPService::nsLDAPService()
|
|||
//
|
||||
nsLDAPService::~nsLDAPService()
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsLDAPService,nsIRunnable);
|
||||
|
||||
// initialize; should only be called by the generic constructor after
|
||||
// creation. This is where the thread gets spun up.
|
||||
// Initializer, create some internal hash tables etc.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsLDAPService::Init(void)
|
||||
nsresult nsLDAPService::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
if (!mLock) {
|
||||
mLock = PR_NewLock();
|
||||
if (!mLock) {
|
||||
NS_ERROR("nsLDAPService::Init: out of memory ");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mThread, "nsLDAPService already initialized!");
|
||||
if (!mServers) {
|
||||
mServers = new nsHashtable(16, PR_FALSE);
|
||||
if (!mServers) {
|
||||
NS_ERROR("nsLDAPService::Init: out of memory ");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
rv = NS_NewThread(getter_AddRefs(mThread),
|
||||
this, 0, PR_JOINABLE_THREAD);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// for nsIRunnable. all the processing work happens here.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsLDAPService::Run(void)
|
||||
{
|
||||
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("nsLDAPService::Run() entered\n"));
|
||||
|
||||
// XXX - should use mThreadRunning here
|
||||
//
|
||||
while (1) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// void addServer (in nsILDAPServer aServer);
|
||||
NS_IMETHODIMP nsLDAPService::AddServer(nsILDAPServer *aServer)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsXPIDLString key;
|
||||
nsresult rv;
|
||||
|
||||
if (!aServer) {
|
||||
NS_ERROR("nsLDAPService::AddServer: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Set up the hash key for the server entry
|
||||
//
|
||||
rv = aServer->GetKey(getter_Copies(key));
|
||||
if (NS_FAILED(rv)) {
|
||||
switch (rv) {
|
||||
// Only pass along errors we are aware of
|
||||
//
|
||||
case NS_ERROR_OUT_OF_MEMORY:
|
||||
case NS_ERROR_NULL_POINTER:
|
||||
return rv;
|
||||
|
||||
default:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the new service server entry, and add it into the hash table
|
||||
//
|
||||
entry = new nsLDAPServiceEntry;
|
||||
if (!entry) {
|
||||
NS_ERROR("nsLDAPService::AddServer: out of memory ");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!entry->Init()) {
|
||||
delete entry;
|
||||
NS_ERROR("nsLDAPService::AddServer: out of memory ");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!entry->SetServer(aServer)) {
|
||||
delete entry;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We increment the refcount here for the server entry, when
|
||||
// we purge a server completely from the service (TBD), we
|
||||
// need to decrement the counter as well.
|
||||
//
|
||||
{
|
||||
nsStringKey hashKey(key);
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (mServers->Exists(&hashKey)) {
|
||||
// Collision detected, lets just throw away this service entry
|
||||
// and keep the old one.
|
||||
//
|
||||
delete entry;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mServers->Put(&hashKey, entry);
|
||||
}
|
||||
NS_ADDREF(aServer);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// void deleteServer (in wstring aKey);
|
||||
NS_IMETHODIMP nsLDAPService::DeleteServer(const PRUnichar *aKey)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
// We should probably rename the key for this entry now that it's
|
||||
// "deleted", so that we can add in a new one with the same ID.
|
||||
// This is bug #77669.
|
||||
//
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (entry) {
|
||||
if (entry->GetLeases() > 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
entry->DeleteEntry();
|
||||
} else {
|
||||
// There is no Server entry for this key
|
||||
//
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsILDAPServer getServer (in wstring aKey);
|
||||
NS_IMETHODIMP nsLDAPService::GetServer(const PRUnichar *aKey,
|
||||
nsILDAPServer **_retval)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (!_retval) {
|
||||
NS_ERROR("nsLDAPService::GetServer: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry) {
|
||||
*_retval = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!(*_retval = entry->GetServer())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//void requestConnection (in wstring aKey,
|
||||
// in nsILDAPMessageListener aMessageListener);
|
||||
NS_IMETHODIMP nsLDAPService::RequestConnection(const PRUnichar *aKey,
|
||||
nsILDAPMessageListener *aListener)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsCOMPtr<nsILDAPConnection> conn;
|
||||
nsCOMPtr<nsILDAPMessage> message;
|
||||
nsresult rv;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
|
||||
if (!aListener) {
|
||||
NS_ERROR("nsLDAPService::RequestConection: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Try to find a possibly cached connection and LDAP message.
|
||||
//
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
entry->SetTimestamp();
|
||||
|
||||
conn = getter_AddRefs(entry->GetConnection());
|
||||
message = getter_AddRefs(entry->GetMessage());
|
||||
}
|
||||
|
||||
if (conn) {
|
||||
if (message) {
|
||||
// We already have the connection, and the message, ready to
|
||||
// be used. This might be confusing, since we actually call
|
||||
// the listener before this function returns, see bug #75899.
|
||||
//
|
||||
aListener->OnLDAPMessage(message);
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
rv = EstablishConnection(entry, aListener);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We got a new connection, now push the listeners on our stack,
|
||||
// until we get the LDAP message back.
|
||||
//
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry ||
|
||||
!entry->PushListener(NS_STATIC_CAST(nsILDAPMessageListener *,
|
||||
aListener))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsILDAPConnection getConnection (in wstring aKey);
|
||||
NS_IMETHODIMP nsLDAPService::GetConnection(const PRUnichar *aKey,
|
||||
nsILDAPConnection **_retval)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (!_retval) {
|
||||
NS_ERROR("nsLDAPService::GetConnection: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry) {
|
||||
*_retval = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
entry->SetTimestamp();
|
||||
entry->IncrementLeases();
|
||||
if (!(*_retval = entry->GetConnection())){
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// void releaseConnection (in wstring aKey);
|
||||
NS_IMETHODIMP nsLDAPService::ReleaseConnection(const PRUnichar *aKey)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (entry->GetLeases() > 0) {
|
||||
entry->SetTimestamp();
|
||||
entry->DecrementLeases();
|
||||
} else {
|
||||
// Releasing a non-leased connection is currently a No-Op.
|
||||
//
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// void reconnectConnection (in wstring aKey,
|
||||
// in nsILDAPMessageListener aMessageListener);
|
||||
NS_IMETHODIMP nsLDAPService::ReconnectConnection(const PRUnichar *aKey,
|
||||
nsILDAPMessageListener *aListener)
|
||||
{
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsresult rv;
|
||||
nsStringKey hashKey(aKey, -1, nsStringKey::NEVER_OWN);
|
||||
|
||||
if (!aListener) {
|
||||
NS_ERROR("nsLDAPService::ReconnectConnection: null pointer ");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *, mServers->Get(&hashKey));
|
||||
if (!entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
entry->SetTimestamp();
|
||||
|
||||
if (entry->IsRebinding()) {
|
||||
if (!entry->PushListener(aListener)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Clear the old connection and message, which should get garbaged
|
||||
// collected now. We mark this as being "rebinding" now, and it
|
||||
// we be marked as finished either if there's an error condition,
|
||||
// or if the OnLDAPMessage() method gets called (i.e. bind() done).
|
||||
//
|
||||
entry->SetMessage(0);
|
||||
entry->SetConnection(0);
|
||||
|
||||
// Get a new connection
|
||||
//
|
||||
entry->SetRebinding(PR_TRUE);
|
||||
}
|
||||
|
||||
rv = EstablishConnection(entry, aListener);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (!entry->PushListener(NS_STATIC_CAST(nsILDAPMessageListener *,
|
||||
aListener))) {
|
||||
entry->SetRebinding(PR_FALSE);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Messages received are passed back via this function.
|
||||
*
|
||||
* @arg aMessage The message that was returned, 0 if none was.
|
||||
*
|
||||
* void OnLDAPMessage (in nsILDAPMessage aMessage)
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLDAPService::OnLDAPMessage(nsILDAPMessage *aMessage)
|
||||
{
|
||||
nsCOMPtr<nsILDAPOperation> operation;
|
||||
nsCOMPtr<nsILDAPConnection> connection;
|
||||
PRInt32 messageType;
|
||||
|
||||
// XXXleif: NULL messages are supposedly allowed, but the semantics
|
||||
// are not definted (yet?). This is something to look out for...
|
||||
//
|
||||
|
||||
|
||||
// figure out what sort of message was returned
|
||||
//
|
||||
nsresult rv = aMessage->GetType(&messageType);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPService::OnLDAPMessage(): unexpected error in "
|
||||
"nsLDAPMessage::GetType()");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
switch (messageType) {
|
||||
case LDAP_RES_BIND:
|
||||
// a bind has completed
|
||||
//
|
||||
rv = aMessage->GetOperation(getter_AddRefs(operation));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPService::OnLDAPMessage(): unexpected error in "
|
||||
"nsLDAPMessage::GetOperation()");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
rv = operation->GetConnection(getter_AddRefs(connection));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPService::OnLDAPMessage(): unexpected error in "
|
||||
"nsLDAPOperation::GetConnection()");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Now we have the connection, lets find the corresponding
|
||||
// server entry in the Service.
|
||||
//
|
||||
{
|
||||
nsCOMPtr<nsILDAPMessageListener> listener;
|
||||
nsCOMPtr<nsILDAPMessage> message;
|
||||
nsLDAPServiceEntry *entry;
|
||||
nsVoidKey connKey(NS_STATIC_CAST(nsILDAPConnection *,
|
||||
connection));
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
entry = NS_STATIC_CAST(nsLDAPServiceEntry *,
|
||||
mConnections->Get(&connKey));
|
||||
if (!entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
message = getter_AddRefs(entry->GetMessage());
|
||||
if (message) {
|
||||
// We already have a message, lets keep that one.
|
||||
//
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
entry->SetRebinding(PR_FALSE);
|
||||
entry->SetMessage(aMessage);
|
||||
|
||||
// Now process all the pending callbacks/listeners. We
|
||||
// have to make sure to unlock before calling a listener,
|
||||
// since it's likely to call back into us again.
|
||||
//
|
||||
while (listener = entry->PopListener()) {
|
||||
lock.unlock();
|
||||
listener->OnLDAPMessage(aMessage);
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_WARNING("nsLDAPService::OnLDAPMessage(): unexpected LDAP message "
|
||||
"received");
|
||||
|
||||
// get the console service so we can log a message
|
||||
//
|
||||
nsCOMPtr<nsIConsoleService> consoleSvc =
|
||||
do_GetService("@mozilla.org/consoleservice;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsLDAPChannel::OnLDAPMessage() couldn't get console "
|
||||
"service");
|
||||
break;
|
||||
}
|
||||
|
||||
// log the message
|
||||
//
|
||||
rv = consoleSvc->LogStringMessage(
|
||||
NS_LITERAL_STRING("LDAP: WARNING: nsLDAPService::OnLDAPMessage(): Unexpected LDAP message received").get());
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "nsLDAPService::OnLDAPMessage(): "
|
||||
"consoleSvc->LogStringMessage() failed");
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper function to establish an LDAP connection properly.
|
||||
//
|
||||
nsresult nsLDAPService::EstablishConnection(nsLDAPServiceEntry *aEntry,
|
||||
nsILDAPMessageListener *aListener)
|
||||
{
|
||||
nsCOMPtr<nsILDAPOperation> operation;
|
||||
nsCOMPtr<nsILDAPServer> server;
|
||||
nsCOMPtr<nsILDAPURL> url;
|
||||
nsCOMPtr<nsILDAPConnection> conn, conn2;
|
||||
nsCOMPtr<nsILDAPMessage> message;
|
||||
nsXPIDLCString host;
|
||||
nsXPIDLString binddn;
|
||||
nsXPIDLString password;
|
||||
PRInt32 port;
|
||||
nsresult rv;
|
||||
|
||||
server = getter_AddRefs(aEntry->GetServer());
|
||||
if (!server) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Get username and password from the server entry.
|
||||
//
|
||||
rv = server->GetBinddn(getter_Copies(binddn));
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = server->GetPassword(getter_Copies(password));
|
||||
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->GetHost(getter_Copies(host));
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = url->GetPort(&port);
|
||||
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, port, 0);
|
||||
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 = getter_AddRefs(aEntry->GetConnection());
|
||||
message = getter_AddRefs(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);
|
||||
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(0);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Dan Mosedale <dmose@mozilla.org>
|
||||
* Contributor(s): Leif Hedstrom <leif@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
|
@ -32,12 +32,19 @@
|
|||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef nsLDAPService_h___
|
||||
#define nsLDAPService_h___
|
||||
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsLDAP.h"
|
||||
#include "ldap.h"
|
||||
#include "nsString.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsILDAPService.h"
|
||||
#include "nsILDAPMessage.h"
|
||||
#include "nsILDAPMessageListener.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsILDAPServer.h"
|
||||
#include "nsILDAPConnection.h"
|
||||
#include "nsILDAPMessage.h"
|
||||
|
||||
|
||||
// 6a89ae33-7a90-430d-888c-0dede53a951a
|
||||
//
|
||||
|
@ -47,28 +54,78 @@
|
|||
{0x88, 0x8c, 0x0d, 0xed, 0xe5, 0x3a, 0x95, 0x1a} \
|
||||
}
|
||||
|
||||
class nsLDAPService : public nsIRunnable
|
||||
// This is a little "helper" class, we use to store information
|
||||
// related to one Service entry (one LDAP server).
|
||||
//
|
||||
class nsLDAPServiceEntry
|
||||
{
|
||||
public:
|
||||
nsLDAPServiceEntry();
|
||||
virtual ~nsLDAPServiceEntry();
|
||||
PRBool Init();
|
||||
|
||||
inline PRUint32 GetLeases();
|
||||
inline void IncrementLeases();
|
||||
inline PRBool DecrementLeases();
|
||||
|
||||
inline PRTime GetTimestamp();
|
||||
inline void SetTimestamp();
|
||||
|
||||
inline nsILDAPServer *GetServer();
|
||||
inline PRBool SetServer(nsILDAPServer *aServer);
|
||||
|
||||
inline nsILDAPConnection *GetConnection();
|
||||
inline void SetConnection(nsILDAPConnection *aConnection);
|
||||
|
||||
inline nsILDAPMessage *GetMessage();
|
||||
inline void SetMessage(nsILDAPMessage *aMessage);
|
||||
|
||||
inline nsILDAPMessageListener *PopListener();
|
||||
inline PRBool PushListener(nsILDAPMessageListener *);
|
||||
|
||||
inline PRBool IsRebinding();
|
||||
inline void SetRebinding(PRBool);
|
||||
|
||||
inline PRBool DeleteEntry();
|
||||
|
||||
protected:
|
||||
PRUint32 mLeases; // The number of leases currently granted
|
||||
PRTime mTimestamp; // Last time this server was "used"
|
||||
PRBool mDelete; // This entry is due for deletion
|
||||
PRBool mRebinding; // Keep state if we are rebinding or not
|
||||
|
||||
nsCOMPtr<nsILDAPServer> mServer;
|
||||
nsCOMPtr<nsILDAPConnection> mConnection;
|
||||
nsCOMPtr<nsILDAPMessage> mMessage;
|
||||
|
||||
// Array holding all the pending callbacks (listeners) for this entry
|
||||
nsCOMPtr<nsISupportsArray> mListeners;
|
||||
};
|
||||
|
||||
// This is the interface we're implementing.
|
||||
//
|
||||
class nsLDAPService : public nsILDAPService, public nsILDAPMessageListener
|
||||
{
|
||||
public:
|
||||
// interface decls
|
||||
//
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSILDAPSERVICE
|
||||
NS_DECL_NSILDAPMESSAGELISTENER
|
||||
|
||||
// constructor and destructor
|
||||
//
|
||||
nsLDAPService();
|
||||
virtual ~nsLDAPService();
|
||||
|
||||
// initialize; should only be called by the generic
|
||||
// constructor after creation
|
||||
//
|
||||
NS_METHOD Init(void);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
PRBool mThreadRunning;
|
||||
nsresult EstablishConnection(nsLDAPServiceEntry *,
|
||||
nsILDAPMessageListener *);
|
||||
|
||||
PRLock *mLock; // Lock mechanism
|
||||
nsHashtable *mServers; // Hash table holding server entries
|
||||
nsHashtable *mConnections; // Hash table holding "reverse"
|
||||
// lookups from connection to server
|
||||
};
|
||||
|
||||
#endif // nsLDAPService_h___
|
||||
|
|
Двоичные данные
directory/xpcom/macbuild/mozldap.mcp
Двоичные данные
directory/xpcom/macbuild/mozldap.mcp
Двоичный файл не отображается.
Двоичные данные
directory/xpcom/macbuild/mozldapIDL.mcp
Двоичные данные
directory/xpcom/macbuild/mozldapIDL.mcp
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче