Bug 419595 nsLDAPURL implementation is incorrect. r=bienvenu,sr=dmose

This commit is contained in:
Mark Banner 2009-01-13 10:37:12 +00:00
Родитель 35caece29a
Коммит bf7b4787a3
21 изменённых файлов: 975 добавлений и 647 удалений

Просмотреть файл

@ -43,8 +43,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
# Note that for the time being "tests" require LDAP Experimental
#
DIRS = \
base \
$(NULL)
@ -53,12 +51,11 @@ ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
DIRS += \
datasource \
$(NULL)
endif
ifdef ENABLE_TESTS
DIRS += \
tests
endif
endif
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -52,8 +52,33 @@
* they can only be of a limited subset of ASCII (see RFC 2251).
*/
[scriptable, uuid(7310562d-1567-43c7-a123-633c1ba3663e)]
[scriptable, uuid(1018ee06-f708-4bd7-b7df-11285332a404)]
interface nsILDAPURL : nsIURI {
/**
* Initialize an LDAP URL
*
* @param aUrlType - one of the URLTYPE_ flags @seealso nsIStandardURL
* @param aDefaultPort - if the port parsed from the URL string matches
* this port, then the port will be removed from the
* canonical form of the URL.
* @param aSpec - URL string.
* @param aOriginCharset - the charset from which this URI string
* originated. this corresponds to the charset
* that should be used when communicating this
* URI to an origin server, for example. if
* null, then provide aBaseURI implements this
* interface, the origin charset of aBaseURI will
* be assumed, otherwise defaulting to UTF-8 (i.e.,
* no charset transformation from aSpec).
* @param aBaseURI - if null, aSpec must specify an absolute URI.
* otherwise, aSpec will be resolved relative
* to aBaseURI.
*/
void init(in unsigned long aUrlType,
in long aDefaultPort,
in AUTF8String aSpec,
in string aOriginCharset,
in nsIURI aBaseURI);
/**
* The distinguished name of the URL (ie the base DN for the search).
@ -151,5 +176,4 @@ interface nsILDAPURL : nsIURI {
* If this is set/true, this is an ldaps: URL, not an ldap: URL
*/
const unsigned long OPT_SECURE = 0x01;
};

Просмотреть файл

@ -56,6 +56,9 @@ REQUIRES = xpcom \
necko \
$(NULL)
EXTRA_PP_COMPONENTS = \
nsLDAPProtocolHandler.js \
$(NULL)
CPPSRCS = \
nsLDAPProtocolModule.cpp \
@ -69,7 +72,6 @@ CPPSRCS = \
nsLDAPControl.cpp \
nsLDAPBERElement.cpp \
nsLDAPModification.cpp \
nsLDAPProtocolHandler.cpp \
$(NULL)
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL

Просмотреть файл

@ -62,6 +62,11 @@
//
#define INVOKE_LDAP_CALLBACKS_ON_MAIN_THREAD 0
// {97cce72b-8ce9-466e-b21d-05da7c1e02a6}
#define NS_LDAPCHANNEL_CID \
{ 0x97cce72b, 0x8ce9, 0x466e, \
{ 0xb2, 0x1d, 0x05, 0xda, 0x7c, 0x1e, 0x02, 0xa6 } }
class nsLDAPChannel : public nsIChannel, public nsILDAPMessageListener
{
public:

Просмотреть файл

@ -1,155 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 SDK.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dan Mosedale <dmose@mozilla.org>
* Brian Ryner <bryner@brianryner.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsLDAPProtocolHandler.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsLDAPURL.h"
#include "nsLDAPChannel.h"
static NS_DEFINE_CID(kLDAPURLCID, NS_LDAPURL_CID);
// QueryInterface, AddRef, and Release
//
NS_IMPL_ISUPPORTS1(nsLDAPProtocolHandler, nsIProtocolHandler)
nsLDAPProtocolHandler::nsLDAPProtocolHandler()
{
}
nsLDAPProtocolHandler::~nsLDAPProtocolHandler()
{
}
// nsIProtocolHandler methods
// getter method for scheme attr
//
NS_IMETHODIMP
nsLDAPProtocolHandler::GetScheme(nsACString &result)
{
result = "ldap";
return NS_OK;
}
// getter method for defaultPort attribute
//
NS_IMETHODIMP
nsLDAPProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = 389;
return NS_OK;
}
// getter method for protocol flags attribute
//
NS_IMETHODIMP
nsLDAPProtocolHandler::GetProtocolFlags(PRUint32 *result)
{
*result = URI_NORELATIVE | URI_DANGEROUS_TO_LOAD;
return NS_OK;
}
// construct an appropriate URI
//
NS_IMETHODIMP
nsLDAPProtocolHandler::NewURI(const nsACString &aSpec,
const char *aOriginCharset, // ignored
nsIURI *aBaseURI,
nsIURI **result)
{
nsCOMPtr<nsILDAPURL> url;
nsresult rv;
url = do_CreateInstance(kLDAPURLCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// XXX - better error handling
//
rv = url->SetSpec(aSpec);
NS_ENSURE_SUCCESS(rv, rv);
// this is a getter, so we need to AddRef on the way out
//
*result = url;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsLDAPProtocolHandler::NewChannel(nsIURI* uri,
nsIChannel* *result)
{
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
NS_ENSURE_ARG_POINTER(uri);
nsresult rv;
nsLDAPChannel *channel;
rv = nsLDAPChannel::Create(0, NS_GET_IID(nsIChannel),
reinterpret_cast<void **>(&channel));
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->Init(uri);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
// the channel was already AddRefed for us, and since this function itself
// is a getter, there's no need to release it here.
//
*result = channel;
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
NS_IMETHODIMP
nsLDAPProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
{
if (port == 389 || port == 636) // 636 is LDAP/SSL
*_retval = PR_TRUE;
else
*_retval = PR_FALSE;
return NS_OK;
}

Просмотреть файл

@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 SDK.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dan Mosedale <dmose@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsLDAPProtocolHandler_h__
#define nsLDAPProtocolHandler_h__
#include "nsIProtocolHandler.h"
// 9817dcda-8a67-4c30-b96f-ec4e647b0043
#define NS_LDAPPROTOCOLHANDLER_CID \
{ 0x9817dcda, 0x8a67, 0x4c30, \
{0xb9, 0x6f, 0xec, 0x4e, 0x64, 0x7b, 0x00, 0x43} \
}
class nsLDAPProtocolHandler : public nsIProtocolHandler
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
nsLDAPProtocolHandler();
virtual ~nsLDAPProtocolHandler();
};
#endif // nsLDAPProtocolHandler_h__

Просмотреть файл

@ -0,0 +1,100 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 LDAP Protocol Handler.
*
* The Initial Developer of the Original Code is
* Mozilla Messaging.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Banner <bugzilla@standard8.plus.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const kNetworkProtocolCIDPrefix = "@mozilla.org/network/protocol;1?name=";
const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
function makeProtocolHandler(aProtocol, aDefaultPort) {
return {
classDescription: "LDAP Protocol Handler",
contractID: kNetworkProtocolCIDPrefix + aProtocol,
classID: Components.ID("{b3de9249-b0e5-4c12-8d91-c9a434fd80f5}"),
QueryInterface: XPCOMUtils.generateQI([nsIProtocolHandler]),
scheme: aProtocol,
defaultPort: aDefaultPort,
protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
nsIProtocolHandler.ALLOWS_PROXY,
newURI: function (aSpec, aOriginCharset, aBaseURI) {
var url = Components.classes["@mozilla.org/network/ldap-url;1"]
.createInstance(Components.interfaces.nsIURI);
if (url instanceof Components.interfaces.nsILDAPURL)
#ifdef USE_TK_LOGIN_MANAGER
url.init(Components.interfaces.nsIStandardURL.URLTYPE_STANDARD,
aDefaultPort, aSpec, aOriginCharset, aBaseURI);
#else
url.init(Components.interfaces.nsIStandardURL.URLTYPE_STANDARD,
-1, aSpec, aOriginCharset, aBaseURI);
#endif
return url;
},
newChannel: function (aURI) {
if ("@mozilla.org/network/ldap-channel;1" in Components.classes) {
var channel = Components.classes["@mozilla.org/network/ldap-channel;1"]
.createInstance(Components.interfaces.nsIChannel);
channel.init(aURI);
return channel;
}
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
allowPort: function (port, scheme) {
return port == aDefaultPort;
}
};
}
function nsLDAPProtocolHandler() {}
nsLDAPProtocolHandler.prototype = makeProtocolHandler("ldap", 389);
function nsLDAPSProtocolHandler() {}
nsLDAPSProtocolHandler.prototype = makeProtocolHandler("ldaps", 636);
function NSGetModule(compMgr, fileSpec) {
return XPCOMUtils.generateModule([nsLDAPProtocolHandler,
nsLDAPSProtocolHandler]);
}

Просмотреть файл

@ -52,7 +52,6 @@
#include "nsLDAPBERValue.h"
#include "nsLDAPBERElement.h"
#include "nsLDAPControl.h"
#include "nsLDAPProtocolHandler.h"
#include "ldappr.h"
@ -67,12 +66,14 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPOperation)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPMessage)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPModification, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPServer)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPURL, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPURL)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPBERValue)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPBERElement)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPControl)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPProtocolHandler)
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPChannel)
#endif
NS_DECL_CLASSINFO(nsLDAPMessage)
NS_DECL_CLASSINFO(nsLDAPOperation)
@ -115,15 +116,16 @@ static const nsModuleComponentInfo components[] =
"@mozilla.org/network/ldap-server;1", nsLDAPServerConstructor },
{ "LDAP Service", NS_LDAPSERVICE_CID,
"@mozilla.org/network/ldap-service;1", nsLDAPServiceConstructor },
{ "LDAP Protocol Handler", NS_LDAPPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ldap",
nsLDAPProtocolHandlerConstructor },
{ "LDAP URL", NS_LDAPURL_CID,
"@mozilla.org/network/ldap-url;1", nsLDAPURLConstructor },
{ "LDAP BER Value", NS_LDAPBERVALUE_CID,
"@mozilla.org/network/ldap-ber-value;1", nsLDAPBERValueConstructor },
{ "LDAP BER Element", NS_LDAPBERELEMENT_CID,
"@mozilla.org/network/ldap-ber-element;1", nsLDAPBERElementConstructor },
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
{ "LDAP Channel", NS_LDAPCHANNEL_CID,
"@mozilla.org/network/ldap-channel;1", nsLDAPChannelConstructor },
#endif
{ "LDAP Control", NS_LDAPCONTROL_CID,
"@mozilla.org/network/ldap-control;1", nsLDAPControlConstructor}
};

Просмотреть файл

@ -43,329 +43,357 @@
#include "netCore.h"
#include "plstr.h"
#include "nsCOMPtr.h"
#include "nsNetCID.h"
#include "nsComponentManagerUtils.h"
#include "nsIStandardURL.h"
// The two schemes we support, LDAP and LDAPS
//
static const char kLDAPScheme[] = "ldap";
static const char kLDAPSSLScheme[] = "ldaps";
NS_NAMED_LITERAL_CSTRING(LDAP_SCHEME, "ldap");
NS_NAMED_LITERAL_CSTRING(LDAP_SSL_SCHEME, "ldaps");
// Constructor and destructor
//
NS_IMPL_THREADSAFE_ISUPPORTS2(nsLDAPURL, nsILDAPURL, nsIURI)
nsLDAPURL::nsLDAPURL()
: mPort(0),
mScope(SCOPE_BASE),
mOptions(0),
mAttributes(0)
: mScope(SCOPE_BASE),
mOptions(0)
{
}
nsLDAPURL::~nsLDAPURL()
{
// Delete the array of attributes
delete mAttributes;
}
nsresult
nsLDAPURL::Init()
nsLDAPURL::Init(PRUint32 aUrlType, PRInt32 aDefaultPort,
const nsACString &aSpec, const char* aOriginCharset,
nsIURI *aBaseURI)
{
if (!mAttributes) {
mAttributes = new nsCStringArray();
if (!mAttributes) {
NS_ERROR("nsLDAPURL::Init: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
if (!mBaseURL)
{
mBaseURL = do_CreateInstance(NS_STANDARDURL_CONTRACTID);
if (!mBaseURL)
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv;
nsCOMPtr<nsIStandardURL> standardURL(do_QueryInterface(mBaseURL, &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = standardURL->Init(aUrlType, aDefaultPort, aSpec, aOriginCharset,
aBaseURI);
NS_ENSURE_SUCCESS(rv, rv);
// Now get the spec from the mBaseURL in case it was a relative one
nsCString spec;
rv = mBaseURL->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
return SetSpec(spec);
}
void
nsLDAPURL::GetPathInternal(nsCString &aPath)
{
aPath.Assign('/');
if (!mDN.IsEmpty())
aPath.Append(mDN);
PRUint32 count = mAttributes.Count();
if (count)
{
aPath.Append('?');
PRUint32 index = 0;
while (index < count)
{
aPath.Append(*(mAttributes.CStringAt(index++)));
if (index < count)
aPath.Append(',');
}
}
if (mScope || !mFilter.IsEmpty())
{
aPath.Append((count ? "?" : "??"));
if (mScope)
{
if (mScope == SCOPE_ONELEVEL)
aPath.Append("one");
else if (mScope == SCOPE_SUBTREE)
aPath.Append("sub");
}
if (!mFilter.IsEmpty())
{
aPath.Append('?');
aPath.Append(mFilter);
}
}
}
nsresult
nsLDAPURL::SetPathInternal(const nsCString &aPath)
{
PRUint32 rv, count;
LDAPURLDesc *desc;
nsCString str;
char **attributes;
// This is from the LDAP C-SDK, which currently doesn't
// support everything from RFC 2255... :(
//
rv = ldap_url_parse(aPath.get(), &desc);
switch (rv) {
case LDAP_SUCCESS:
// The base URL can pick up the host & port details and deal with them
// better than we can
mDN = desc->lud_dn;
mScope = desc->lud_scope;
mFilter = desc->lud_filter;
mOptions = desc->lud_options;
// Set the attributes array, need to count it first.
//
count = 0;
attributes = desc->lud_attrs;
while (attributes && *attributes++)
count++;
if (count) {
rv = SetAttributes(count, const_cast<const char **>(desc->lud_attrs));
// This error could only be out-of-memory, so pass it up
//
if (NS_FAILED(rv)) {
return rv;
}
} else {
mAttributes.Clear();
}
ldap_free_urldesc(desc);
return NS_OK;
case LDAP_URL_ERR_NOTLDAP:
case LDAP_URL_ERR_NODN:
case LDAP_URL_ERR_BADSCOPE:
return NS_ERROR_MALFORMED_URI;
case LDAP_URL_ERR_MEM:
NS_ERROR("nsLDAPURL::SetSpec: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
case LDAP_URL_ERR_PARAM:
return NS_ERROR_INVALID_POINTER;
}
// This shouldn't happen...
return NS_ERROR_UNEXPECTED;
}
// A string representation of the URI. Setting the spec
// causes the new spec to be parsed, initializing the URI. Setting
// the spec (or any of the accessors) causes also any currently
// open streams on the URI's channel to be closed.
//
// attribute string spec;
//
NS_IMETHODIMP
nsLDAPURL::GetSpec(nsACString &_retval)
{
nsCAutoString spec;
PRUint32 count;
spec = ((mOptions & OPT_SECURE) ? kLDAPSSLScheme : kLDAPScheme);
spec.Append("://");
if (!mHost.IsEmpty()) {
spec.Append(mHost);
}
if (mPort > 0) {
spec.Append(':');
spec.AppendInt(mPort);
}
spec.Append('/');
if (!mDN.IsEmpty()) {
spec.Append(mDN);
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
if ((count = mAttributes->Count())) {
PRUint32 index = 0;
spec.Append('?');
while (index < count) {
spec.Append(*(mAttributes->CStringAt(index++)));
if (index < count) {
spec.Append(',');
}
}
}
if (mScope || !mFilter.IsEmpty()) {
spec.Append((count ? "?" : "??"));
if (mScope) {
if (mScope == SCOPE_ONELEVEL) {
spec.Append("one");
} else if (mScope == SCOPE_SUBTREE) {
spec.Append("sub");
}
}
if (!mFilter.IsEmpty()) {
spec.Append('?');
spec.Append(mFilter);
}
}
_retval = spec;
return NS_OK;
return mBaseURL->GetSpec(_retval);
}
NS_IMETHODIMP
nsLDAPURL::SetSpec(const nsACString &aSpec)
{
PRUint32 rv, count;
LDAPURLDesc *desc;
nsCString str;
char **attributes;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
// This is from the LDAP C-SDK, which currently doesn't
// support everything from RFC 2255... :(
//
rv = ldap_url_parse(PromiseFlatCString(aSpec).get(), &desc);
switch (rv) {
case LDAP_SUCCESS:
mHost = desc->lud_host;
mPort = desc->lud_port;
mDN = desc->lud_dn;
mScope = desc->lud_scope;
mFilter = desc->lud_filter;
mOptions = desc->lud_options;
// Cache the original spec in case we don't like what we've been passed and
// need to reset ourselves.
nsCString originalSpec;
nsresult rv = mBaseURL->GetSpec(originalSpec);
NS_ENSURE_SUCCESS(rv, rv);
// Set the attributes array, need to count it first.
//
count = 0;
attributes = desc->lud_attrs;
while (attributes && *attributes++) {
count++;
}
if (count) {
rv = SetAttributes(count,
const_cast<const char **>(desc->lud_attrs));
// This error could only be out-of-memory, so pass it up
//
if (NS_FAILED(rv)) {
return rv;
}
} else {
mAttributes->Clear();
}
rv = mBaseURL->SetSpec(aSpec);
NS_ENSURE_SUCCESS(rv, rv);
ldap_free_urldesc(desc);
return NS_OK;
rv = SetPathInternal(nsPromiseFlatCString(aSpec));
if (NS_FAILED(rv))
mBaseURL->SetSpec(originalSpec);
case LDAP_URL_ERR_NOTLDAP:
case LDAP_URL_ERR_NODN:
case LDAP_URL_ERR_BADSCOPE:
return NS_ERROR_MALFORMED_URI;
case LDAP_URL_ERR_MEM:
NS_ERROR("nsLDAPURL::SetSpec: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
case LDAP_URL_ERR_PARAM:
return NS_ERROR_INVALID_POINTER;
}
// This shouldn't happen...
return NS_ERROR_UNEXPECTED;
return rv;
}
// attribute string prePath;
//
NS_IMETHODIMP nsLDAPURL::GetPrePath(nsACString &_retval)
{
_retval.Truncate();
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetPrePath(_retval);
}
// attribute string scheme;
//
NS_IMETHODIMP nsLDAPURL::GetScheme(nsACString &_retval)
{
_retval = (mOptions & OPT_SECURE) ? kLDAPSSLScheme : kLDAPScheme;
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetScheme(_retval);
}
NS_IMETHODIMP nsLDAPURL::SetScheme(const nsACString &aScheme)
{
if (aScheme.Equals(kLDAPScheme, nsCaseInsensitiveCStringComparator())) {
mOptions ^= OPT_SECURE;
} else if (aScheme.Equals(kLDAPSSLScheme, nsCaseInsensitiveCStringComparator())) {
mOptions |= OPT_SECURE;
} else {
return NS_ERROR_MALFORMED_URI;
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
if (aScheme.Equals(LDAP_SCHEME, nsCaseInsensitiveCStringComparator()))
mOptions &= !OPT_SECURE;
else if (aScheme.Equals(LDAP_SSL_SCHEME,
nsCaseInsensitiveCStringComparator()))
mOptions |= OPT_SECURE;
else
return NS_ERROR_MALFORMED_URI;
return mBaseURL->SetScheme(aScheme);
}
// attribute string userPass;
//
NS_IMETHODIMP
nsLDAPURL::GetUserPass(nsACString &_retval)
{
_retval.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsLDAPURL::SetUserPass(const nsACString &aPreHost)
{
return NS_ERROR_NOT_IMPLEMENTED;
_retval.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsLDAPURL::SetUserPass(const nsACString &aUserPass)
{
return NS_OK;
}
// attribute string username
//
NS_IMETHODIMP
nsLDAPURL::GetUsername(nsACString &_retval)
{
_retval.Truncate();
return NS_OK;
_retval.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsLDAPURL::SetUsername(const nsACString &aUsername)
{
return NS_ERROR_NOT_IMPLEMENTED;
return NS_OK;
}
// attribute string password;
//
NS_IMETHODIMP
nsLDAPURL::GetPassword(nsACString &_retval)
{
_retval.Truncate();
return NS_OK;
_retval.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsLDAPURL::SetPassword(const nsACString &aPassword)
{
return NS_ERROR_NOT_IMPLEMENTED;
return NS_OK;
}
// attribute string hostPort;
//
NS_IMETHODIMP
nsLDAPURL::GetHostPort(nsACString &_retval)
{
nsCString result(mHost);
result.AppendLiteral(":");
if (mPort)
result.AppendInt(mPort);
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
_retval.Assign(result);
return NS_OK;
return mBaseURL->GetHostPort(_retval);
}
NS_IMETHODIMP
nsLDAPURL::SetHostPort(const nsACString &aHostPort)
{
return NS_ERROR_NOT_IMPLEMENTED;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->SetHostPort(aHostPort);
}
// attribute string host;
//
NS_IMETHODIMP
nsLDAPURL::GetHost(nsACString &_retval)
{
_retval = mHost;
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetHost(_retval);
}
NS_IMETHODIMP
nsLDAPURL::SetHost(const nsACString &aHost)
{
mHost = aHost;
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->SetHost(aHost);
}
// C-SDK URL parser defaults port 389 as "0", while nsIURI
// specifies the default to be "-1", hence the translations.
//
// attribute long port;
//
NS_IMETHODIMP
nsLDAPURL::GetPort(PRInt32 *_retval)
{
if (!_retval) {
NS_ERROR("nsLDAPURL::GetPort: null pointer ");
return NS_ERROR_NULL_POINTER;
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
if (!mPort) {
*_retval = -1;
} else {
*_retval = mPort;
}
return NS_OK;
return mBaseURL->GetPort(_retval);
}
NS_IMETHODIMP
nsLDAPURL::SetPort(PRInt32 aPort)
{
if (aPort == -1) {
mPort = 0;
} else if (aPort >= 0) {
mPort = aPort;
} else {
return NS_ERROR_MALFORMED_URI;
}
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->SetPort(aPort);
}
// attribute string path;
// XXXleif: For now, these are identical to SetDn()/GetDn().
NS_IMETHODIMP nsLDAPURL::GetPath(nsACString &_retval)
{
_retval = mDN;
return NS_OK;
}
NS_IMETHODIMP nsLDAPURL::SetPath(const nsACString &aPath)
{
mDN = aPath;
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetPath(_retval);
}
NS_IMETHODIMP nsLDAPURL::SetPath(const nsACString &aPath)
{
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = SetPathInternal(nsPromiseFlatCString(aPath));
NS_ENSURE_SUCCESS(rv, rv);
return mBaseURL->SetPath(aPath);
}
// attribute string specA
NS_IMETHODIMP nsLDAPURL::GetAsciiSpec(nsACString &_retval)
{
return GetSpec(_retval);
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
// XXX handle extra items?
return mBaseURL->GetAsciiSpec(_retval);
}
// attribute string hostA
NS_IMETHODIMP nsLDAPURL::GetAsciiHost(nsACString &_retval)
{
return GetHost(_retval);
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetAsciiHost(_retval);
}
NS_IMETHODIMP nsLDAPURL::GetOriginCharset(nsACString &result)
{
result.Truncate();
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return mBaseURL->GetOriginCharset(result);
}
// boolean equals (in nsIURI other)
@ -400,23 +428,36 @@ NS_IMETHODIMP nsLDAPURL::Equals(nsIURI *other, PRBool *_retval)
// boolean schemeIs(in const char * scheme);
//
NS_IMETHODIMP nsLDAPURL::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
NS_IMETHODIMP nsLDAPURL::SchemeIs(const char *aScheme, PRBool *aEquals)
{
if (!i_Scheme) return NS_ERROR_INVALID_ARG;
if (*i_Scheme == 'l' || *i_Scheme == 'L') {
*o_Equals = PL_strcasecmp("ldap", i_Scheme) ? PR_FALSE : PR_TRUE;
} else {
*o_Equals = PR_FALSE;
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
return mBaseURL->SchemeIs(aScheme, aEquals);
}
// nsIURI clone ();
//
NS_IMETHODIMP nsLDAPURL::Clone(nsIURI **_retval)
NS_IMETHODIMP nsLDAPURL::Clone(nsIURI **aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG_POINTER(aResult);
nsLDAPURL *clone;
NS_NEWXPCOM(clone, nsLDAPURL);
if (!clone)
return NS_ERROR_OUT_OF_MEMORY;
clone->mDN = mDN;
clone->mScope = mScope;
clone->mFilter = mFilter;
clone->mOptions = mOptions;
clone->mAttributes = mAttributes;
nsresult rv = mBaseURL->Clone(getter_AddRefs(clone->mBaseURL));
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = clone);
return NS_OK;
}
// string resolve (in string relativePath);
@ -424,7 +465,7 @@ NS_IMETHODIMP nsLDAPURL::Clone(nsIURI **_retval)
NS_IMETHODIMP nsLDAPURL::Resolve(const nsACString &relativePath,
nsACString &_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
return NS_ERROR_NOT_IMPLEMENTED;
}
// The following attributes come from nsILDAPURL
@ -438,8 +479,17 @@ NS_IMETHODIMP nsLDAPURL::GetDn(nsACString& _retval)
}
NS_IMETHODIMP nsLDAPURL::SetDn(const nsACString& aDn)
{
mDN.Assign(aDn);
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
mDN.Assign(aDn);
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// void getAttributes (out unsigned long aCount,
@ -447,6 +497,9 @@ NS_IMETHODIMP nsLDAPURL::SetDn(const nsACString& aDn)
//
NS_IMETHODIMP nsLDAPURL::GetAttributes(PRUint32 *aCount, char ***_retval)
{
NS_ENSURE_ARG_POINTER(aCount);
NS_ENSURE_ARG_POINTER(_retval);
PRUint32 index = 0;
PRUint32 count;
char **cArray = nsnull;
@ -456,7 +509,7 @@ NS_IMETHODIMP nsLDAPURL::GetAttributes(PRUint32 *aCount, char ***_retval)
return NS_ERROR_NULL_POINTER;
}
count = mAttributes->Count();
count = mAttributes.Count();
if (count > 0) {
cArray = static_cast<char **>(nsMemory::Alloc(count * sizeof(char *)));
if (!cArray) {
@ -467,7 +520,7 @@ NS_IMETHODIMP nsLDAPURL::GetAttributes(PRUint32 *aCount, char ***_retval)
// Loop through the string array, and build up the C-array.
//
while (index < count) {
if (!(cArray[index] = ToNewCString(*(mAttributes->CStringAt(index))))) {
if (!(cArray[index] = ToNewCString(*(mAttributes.CStringAt(index))))) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, cArray);
NS_ERROR("nsLDAPURL::GetAttributes: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
@ -484,97 +537,107 @@ NS_IMETHODIMP nsLDAPURL::GetAttributes(PRUint32 *aCount, char ***_retval)
// [array, size_is (aCount)] in string aAttrs); */
NS_IMETHODIMP nsLDAPURL::SetAttributes(PRUint32 count, const char **aAttrs)
{
PRUint32 index = 0;
nsCString str;
mAttributes->Clear();
while (index < count) {
// Have to assign the str into this temporary nsCString, to make
// the compilers happy...
//
str = nsDependentCString(aAttrs[index]);
if (!mAttributes->InsertCStringAt(str, index++)) {
NS_ERROR("nsLDAPURL::SetAttributes: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
if (count)
NS_ENSURE_ARG_POINTER(aAttrs);
mAttributes.Clear();
for (PRUint32 i = 0; i < count; ++i)
{
if (!mAttributes.AppendCString(nsDependentCString(aAttrs[i])))
{
NS_ERROR("nsLDAPURL::SetAttributes: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
}
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// void addAttribute (in string aAttribute);
//
NS_IMETHODIMP nsLDAPURL::AddAttribute(const char *aAttribute)
{
nsCString str;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
str = nsDependentCString(aAttribute);
if (mAttributes->IndexOfIgnoreCase(str) >= 0) {
return NS_OK;
}
NS_ENSURE_ARG_POINTER(aAttribute);
if (!mAttributes->InsertCStringAt(str, mAttributes->Count())) {
NS_ERROR("nsLDAPURL::AddAttribute: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
nsDependentCString str(aAttribute);
if (mAttributes.IndexOfIgnoreCase(str) >= 0)
return NS_OK;
if (!mAttributes.AppendCString(str)) {
NS_ERROR("nsLDAPURL::AddAttribute: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// void removeAttribute (in string aAttribute);
//
NS_IMETHODIMP nsLDAPURL::RemoveAttribute(const char *aAttribute)
{
nsCString str;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
str = nsDependentCString(aAttribute);
mAttributes->RemoveCString(str);
NS_ENSURE_ARG_POINTER(aAttribute);
mAttributes.RemoveCString(nsDependentCString(aAttribute));
return NS_OK;
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// boolean hasAttribute (in string aAttribute);
//
NS_IMETHODIMP nsLDAPURL::HasAttribute(const char *aAttribute, PRBool *_retval)
{
nsCString str;
NS_ENSURE_ARG_POINTER(aAttribute);
NS_ENSURE_ARG_POINTER(_retval);
if (!_retval) {
NS_ERROR("nsLDAPURL::HasAttribute: null pointer ");
return NS_ERROR_NULL_POINTER;
}
str = nsDependentCString(aAttribute);
*_retval = mAttributes->IndexOfIgnoreCase(str) >= 0;
return NS_OK;
*_retval = mAttributes.IndexOfIgnoreCase(nsDependentCString(aAttribute)) >= 0;
return NS_OK;
}
// attribute long scope;
//
NS_IMETHODIMP nsLDAPURL::GetScope(PRInt32 *_retval)
{
if (!_retval) {
NS_ERROR("nsLDAPURL::GetScope: null pointer ");
return NS_ERROR_NULL_POINTER;
}
*_retval = mScope;
return NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mScope;
return NS_OK;
}
NS_IMETHODIMP nsLDAPURL::SetScope(PRInt32 aScope)
{
// Only allow scopes supported by the C-SDK
if ((aScope != SCOPE_BASE) &&
(aScope != SCOPE_ONELEVEL) &&
(aScope != SCOPE_SUBTREE)) {
return NS_ERROR_MALFORMED_URI;
}
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
mScope = aScope;
// Only allow scopes supported by the C-SDK
if ((aScope != SCOPE_BASE) && (aScope != SCOPE_ONELEVEL) &&
(aScope != SCOPE_SUBTREE))
return NS_ERROR_MALFORMED_URI;
return NS_OK;
mScope = aScope;
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// attribute string filter;
//
NS_IMETHODIMP nsLDAPURL::GetFilter(nsACString& _retval)
{
_retval.Assign(mFilter);
@ -582,24 +645,39 @@ NS_IMETHODIMP nsLDAPURL::GetFilter(nsACString& _retval)
}
NS_IMETHODIMP nsLDAPURL::SetFilter(const nsACString& aFilter)
{
mFilter.Assign(aFilter);
return NS_OK;
if (!mBaseURL)
return NS_ERROR_NOT_INITIALIZED;
mFilter.Assign(aFilter);
if (mFilter.IsEmpty())
mFilter.AssignLiteral("(objectclass=*)");
// Now get the current path
nsCString newPath;
GetPathInternal(newPath);
// and update the base url
return mBaseURL->SetPath(newPath);
}
// attribute unsigned long options;
//
NS_IMETHODIMP nsLDAPURL::GetOptions(PRUint32 *_retval)
{
if (!_retval) {
NS_ERROR("nsLDAPURL::GetOptions: null pointer ");
return NS_ERROR_NULL_POINTER;
}
*_retval = mOptions;
return NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mOptions;
return NS_OK;
}
NS_IMETHODIMP nsLDAPURL::SetOptions(PRUint32 aOptions)
{
mOptions = aOptions;
// Secure is the only option supported at the moment
if (mOptions & OPT_SECURE == aOptions & OPT_SECURE)
return NS_OK;
mOptions = aOptions;
if (aOptions & OPT_SECURE == OPT_SECURE)
return SetScheme(LDAP_SSL_SCHEME);
return SetScheme(LDAP_SCHEME);
}

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -42,29 +42,47 @@
#include "nsString.h"
#include "nsVoidArray.h"
#include "nsILDAPURL.h"
#include "nsCOMPtr.h"
// cb7c67f8-0053-4072-89e9-501cbd1b35ab
#define NS_LDAPURL_CID \
{ 0xcb7c67f8, 0x0053, 0x4072, \
{ 0x89, 0xe9, 0x50, 0x1c, 0xbd, 0x1b, 0x35, 0xab}}
/**
* nsLDAPURL
*
* nsLDAPURL uses an nsStandardURL stored in mBaseURL as its main url formatter.
*
* This is done to ensure that the pre-path sections of the URI are correctly
* formatted and to re-use the functions for nsIURI as appropriate.
*
* Handling of the path sections of the URI are done within nsLDAPURL/parts of
* the LDAP c-sdk. nsLDAPURL holds the individual sections of the path of the
* URI locally (to allow convenient get/set), but always updates the mBaseURL
* when one changes to ensure that mBaseURL.spec and the local data are kept
* consistent.
*/
class nsLDAPURL : public nsILDAPURL
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSILDAPURL
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSILDAPURL
nsLDAPURL();
virtual ~nsLDAPURL();
nsresult Init();
nsLDAPURL();
virtual ~nsLDAPURL();
protected:
nsCString mHost; // Host name of this Directory server
PRInt32 mPort; // LDAP port number
nsCString mDN; // Base Distinguished Name (Base DN)
PRInt32 mScope; // Search scope (base, one or sub)
nsCString mFilter; // LDAP search filter
PRUint32 mOptions; // Options
nsCStringArray *mAttributes; // List of attributes
protected:
void GetPathInternal(nsCString &aPath);
nsresult SetPathInternal(const nsCString &aPath);
nsCString mDN; // Base Distinguished Name (Base DN)
PRInt32 mScope; // Search scope (base, one or sub)
nsCString mFilter; // LDAP search filter
PRUint32 mOptions; // Options
nsCStringArray mAttributes; // List of attributes
nsCOMPtr<nsIURI> mBaseURL;
};

Просмотреть файл

@ -43,10 +43,19 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = rdfldapds
# Module name for xpcshell tests.
MODULE = test_ldapxpcom
XPCSHELL_TESTS = unit
include $(topsrcdir)/config/rules.mk
# Note that for the time being "ldapshell" requires LDAP Experimental
#
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
DEFINES += -DMOZ_LDAP_XPCOM_EXPERIMENTAL
ifeq ($(OS_ARCH),WINNT)
# need this because xpcshell built with readline won't work in cygwin shells
@ -62,3 +71,4 @@ ldapshell:
$(CYGWIN_WRAPPER) $(RUN) $(XPCSHELL) \
-f $(srcdir)/ldapshell.js \
-f -
endif

Просмотреть файл

@ -1,3 +1,5 @@
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
comm.jar:
content/communicator/ldapviewer/example.xul
content/communicator/ldapviewer/example.rdf
#endif

Просмотреть файл

@ -0,0 +1,283 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Test suite for nsLDAPURL functions.
*/
const Ci = Components.interfaces;
const Cc = Components.classes;
// If we are still using the wallet service, then default port numbers
// are still visible in the password manager, and therefore we need to have
// them in the url. The toolkit login manager doesn't do this.
const usingWallet = "nsIWalletService" in Ci;
const portAdpt = usingWallet ? ":389" : "";
const ldapURLs =
[ { url: "ldap://localhost/dc=test",
spec: "ldap://localhost/dc=test",
asciiSpec: "ldap://localhost/dc=test",
host: "localhost",
asciiHost: "localhost",
port: -1,
scheme: "ldap",
path: "/dc=test",
prePath: "ldap://localhost",
hostPort: "localhost",
dn: "dc=test",
scope: Ci.nsILDAPURL.SCOPE_BASE,
filter: "(objectclass=*)",
options: 0
},
{ url: "ldap://localhost:389/dc=test,dc=abc??sub?(objectclass=*)",
spec: "ldap://localhost" + portAdpt + "/dc=test,dc=abc??sub?(objectclass=*)",
asciiSpec: "ldap://localhost" + portAdpt + "/dc=test,dc=abc??sub?(objectclass=*)",
host: "localhost",
asciiHost: "localhost",
port: usingWallet ? 389 : -1,
scheme: "ldap",
path: "/dc=test,dc=abc??sub?(objectclass=*)",
prePath: "ldap://localhost" + portAdpt,
hostPort: "localhost" + portAdpt,
dn: "dc=test,dc=abc",
scope: Ci.nsILDAPURL.SCOPE_SUBTREE,
filter: "(objectclass=*)",
options: 0
},
{ url: "ldap://\u65e5\u672c\u8a93.jp:389/dc=tes\u65e5t??one?(oc=xyz)",
spec: "ldap://\u65e5\u672c\u8a93.jp" + portAdpt + "/dc=tes%E6%97%A5t??one?(oc=xyz)",
asciiSpec: "ldap://xn--wgv71a309e.jp" + portAdpt + "/dc=tes%E6%97%A5t??one?(oc=xyz)",
host: "\u65e5\u672c\u8a93.jp",
asciiHost: "xn--wgv71a309e.jp",
port: usingWallet ? 389 : -1,
scheme: "ldap",
path: "/dc=tes%E6%97%A5t??one?(oc=xyz)",
prePath: "ldap://\u65e5\u672c\u8a93.jp" + portAdpt,
hostPort: "\u65e5\u672c\u8a93.jp" + portAdpt,
dn: "dc=tes\u65e5t",
scope: Ci.nsILDAPURL.SCOPE_ONELEVEL,
filter: "(oc=xyz)",
options: 0
},
{ url: "ldaps://localhost/dc=test",
spec: "ldaps://localhost/dc=test",
asciiSpec: "ldaps://localhost/dc=test",
host: "localhost",
asciiHost: "localhost",
port: -1,
scheme: "ldaps",
path: "/dc=test",
prePath: "ldaps://localhost",
hostPort: "localhost",
dn: "dc=test",
scope: Ci.nsILDAPURL.SCOPE_BASE,
filter: "(objectclass=*)",
options: Ci.nsILDAPURL.OPT_SECURE
}
];
function run_test() {
var url;
// Get the IO service;
var ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
// Test - get and check urls.
var part = 0;
for (part = 0; part < ldapURLs.length; ++part)
{
dump("url: " + ldapURLs[part].url + "\n");
url = ioService.newURI(ldapURLs[part].url, null, null);
do_check_eq(url.spec, ldapURLs[part].spec);
do_check_eq(url.asciiSpec, ldapURLs[part].asciiSpec);
do_check_eq(url.scheme, ldapURLs[part].scheme);
do_check_eq(url.host, ldapURLs[part].host);
do_check_eq(url.asciiHost, ldapURLs[part].asciiHost);
do_check_eq(url.port, ldapURLs[part].port);
do_check_eq(url.path, ldapURLs[part].path);
do_check_eq(url.prePath, ldapURLs[part].prePath);
do_check_eq(url.hostPort, ldapURLs[part].hostPort);
// XXX nsLDAPURL ought to have classinfo.
url = url.QueryInterface(Ci.nsILDAPURL);
do_check_eq(url.dn, ldapURLs[part].dn);
do_check_eq(url.scope, ldapURLs[part].scope);
do_check_eq(url.filter, ldapURLs[part].filter);
do_check_eq(url.options, ldapURLs[part].options);
}
// Test - Check changing ldap values
dump("Other Tests\n");
// Start off with a base url
const kBaseURL = "ldap://localhost:389/dc=test,dc=abc??sub?(objectclass=*)";
url = ioService.newURI(kBaseURL, null, null)
.QueryInterface(Ci.nsILDAPURL);
// Test - dn
url.dn = "dc=short";
do_check_eq(url.dn, "dc=short");
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??sub?(objectclass=*)");
// Test - scope
url.scope = Ci.nsILDAPURL.SCOPE_BASE;
do_check_eq(url.scope, Ci.nsILDAPURL.SCOPE_BASE);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short???(objectclass=*)");
url.scope = Ci.nsILDAPURL.SCOPE_ONELEVEL;
do_check_eq(url.scope, Ci.nsILDAPURL.SCOPE_ONELEVEL);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
// Test - filter
url.filter = "(oc=ygh)";
do_check_eq(url.filter, "(oc=ygh)");
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(oc=ygh)");
url.filter = "";
do_check_eq(url.filter, "(objectclass=*)");
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
// Test - scheme
// An old version used to have a bug whereby if you set the scheme to the
// same thing twice, you'd get the options set wrongly.
url.scheme = "ldaps";
do_check_eq(url.options, 1);
do_check_eq(url.spec, "ldaps://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
url.scheme = "ldaps";
do_check_eq(url.options, 1);
do_check_eq(url.spec, "ldaps://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
do_check_true(url.schemeIs("ldaps"));
do_check_false(url.schemeIs("ldap"));
url.scheme = "ldap";
do_check_eq(url.options, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
url.scheme = "ldap";
do_check_eq(url.options, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
do_check_true(url.schemeIs("ldap"));
do_check_false(url.schemeIs("ldaps"));
// Test - Options
url.options = Ci.nsILDAPURL.OPT_SECURE;
do_check_eq(url.options, Ci.nsILDAPURL.OPT_SECURE);
do_check_eq(url.spec, "ldaps://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
url.options = 0;
do_check_eq(url.options, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
// Test - Equals
var url2 = ioService.newURI("ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)", null, null)
.QueryInterface(Ci.nsILDAPURL);
do_check_true(url.equals(url2));
url2.spec = "ldap://localhost:389/dc=short??sub?(objectclass=*)";
do_check_false(url.equals(url2));
// Test Attributes
var attrs = url.getAttributes({});
do_check_eq(attrs.length, 0);
// Nothing should happend if the attribute doesn't exist
url.removeAttribute("abc");
attrs = url.getAttributes({});
do_check_eq(attrs.length, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
url.addAttribute("dn");
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short?dn?one?(objectclass=*)");
attrs = url.getAttributes({});
do_check_eq(attrs.length, 1);
do_check_eq(attrs[0], "dn");
url.removeAttribute("dn");
attrs = url.getAttributes({});
do_check_eq(attrs.length, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
var newAttrs = [ "abc", "def", "ghi", "jkl" ];
url.setAttributes(newAttrs.length, newAttrs);
var i;
attrs = url.getAttributes({});
do_check_eq(attrs.length, newAttrs.length);
for (i = 0; i < newAttrs.length; ++i)
do_check_eq(attrs[i], newAttrs[i]);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short?abc,def,ghi,jkl?one?(objectclass=*)");
do_check_true(url.hasAttribute("jkl"));
do_check_true(url.hasAttribute("def"));
do_check_true(url.hasAttribute("ABC"));
do_check_false(url.hasAttribute("cde"));
do_check_false(url.hasAttribute("3446"));
url.removeAttribute("abc");
attrs = url.getAttributes({});
do_check_eq(attrs.length, newAttrs.length - 1);
for (i = 0; i < newAttrs.length - 1; ++i)
do_check_eq(attrs[i], newAttrs[i + 1]);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short?def,ghi,jkl?one?(objectclass=*)");
// This shouldn't fail, just clear the list
url.setAttributes(0, []);
attrs = url.getAttributes({});
do_check_eq(attrs.length, 0);
do_check_eq(url.spec, "ldap://localhost" + portAdpt + "/dc=short??one?(objectclass=*)");
// Set attributes via the url spec
url.spec = "ldap://localhost/dc=short?abc,def,ghi,jkl?one?(objectclass=*)";
attrs = url.getAttributes({});
do_check_eq(attrs.length, newAttrs.length);
for (i = 0; i < newAttrs.length; ++i)
do_check_eq(attrs[i], newAttrs[i]);
do_check_eq(url.spec, "ldap://localhost/dc=short?abc,def,ghi,jkl?one?(objectclass=*)");
url.spec = "ldap://localhost/dc=short??one?(objectclass=*)";
attrs = url.getAttributes({});
do_check_eq(attrs.length, 0);
do_check_eq(url.spec, "ldap://localhost/dc=short??one?(objectclass=*)");
// Test - clone
url.spec = "ldap://localhost/dc=short?abc,def,ghi,jkl?one?(objectclass=*)";
var newUrl = url.clone();
do_check_eq(newUrl.spec,
"ldap://localhost/dc=short?abc,def,ghi,jkl?one?(objectclass=*)");
}

Просмотреть файл

@ -188,7 +188,6 @@ function fillSettings()
document.getElementById("results").value = gCurrentDirectory.maxHits;
document.getElementById("login").value = gCurrentDirectory.authDn;
document.getElementById("hostname").value = ldapUrl.host;
document.getElementById("port").value = ldapUrl.port;
document.getElementById("basedn").value = ldapUrl.dn;
document.getElementById("search").value = ldapUrl.filter;
@ -201,9 +200,16 @@ function fillSettings()
sub.radioGroup.selectedItem = sub;
break;
}
if (ldapUrl.options & ldapUrl.OPT_SECURE)
var secure = ldapUrl.options & ldapUrl.OPT_SECURE
if (secure)
document.getElementById("secure").setAttribute("checked", "true");
if (ldapUrl.port == -1)
document.getElementById("port").value =
(secure ? kDefaultSecureLDAPPort : kDefaultLDAPPort);
else
document.getElementById("port").value = ldapUrl.port;
}
// check if any of the preferences for this server are locked.
@ -285,10 +291,6 @@ function onAccept()
var pref_string_content = "";
var pref_string_title = "";
var ldapUrl = Components.classes["@mozilla.org/network/ldap-url;1"];
ldapUrl = ldapUrl.createInstance().
QueryInterface(Components.interfaces.nsILDAPURL);
var description = document.getElementById("description").value;
var hostname = document.getElementById("hostname").value;
var port = document.getElementById("port").value;
@ -305,29 +307,29 @@ function onAccept()
else if (results && hasCharacters(results))
errorValue = "invalidResults";
if (!errorValue) {
// XXX Due to the LDAP c-sdk pass a dummy url to the IO service, then
// update the parts (bug 473351).
var ldapUrl = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI((secure.checked ? "ldaps://" : "ldap://") + "localhost/dc=???",
null, null)
.QueryInterface(Components.interfaces.nsILDAPURL);
ldapUrl.host = hostname;
ldapUrl.port = port ? port :
(secure.checked ? kDefaultSecureLDAPPort :
kDefaultLDAPPort);
ldapUrl.dn = document.getElementById("basedn").value;
ldapUrl.scope = document.getElementById("one").selected ?
Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL :
Components.interfaces.nsILDAPURL.SCOPE_SUBTREE;
ldapUrl.filter = document.getElementById("search").value;
if (!port) {
if (secure.checked)
ldapUrl.port = kDefaultSecureLDAPPort;
else
ldapUrl.port = kDefaultLDAPPort;
} else {
ldapUrl.port = port;
}
if (document.getElementById("one").selected) {
ldapUrl.scope = Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL;
} else {
ldapUrl.scope = Components.interfaces.nsILDAPURL.SCOPE_SUBTREE;
}
if (secure.checked)
ldapUrl.options |= ldapUrl.OPT_SECURE;
// check if we are modifying an existing directory or adding a new directory
if (gCurrentDirectory) {
gCurrentDirectory.dirName = description;
gCurrentDirectory.lDAPURL = ldapUrl;
gCurrentDirectory.lDAPURL = ldapUrl.QueryInterface(Components.interfaces.nsILDAPURL);
window.opener.gNewServerString = gCurrentDirectory.dirPrefId;
}
else { // adding a new directory

Просмотреть файл

@ -67,7 +67,7 @@ interface nsIAbCard;
* draft-joslin-config-schema-11.txt), we can simplify this and other
* code and only allow a property to map to a single attribute.
*/
[scriptable, uuid(bc543118-db5d-4616-b2d4-9a8667609a7c)]
[scriptable, uuid(dbfb9974-45ee-41c3-a005-2e8f002c1c9f)]
interface nsIAbLDAPAttributeMap : nsISupports
{
/**
@ -139,11 +139,12 @@ interface nsIAbLDAPAttributeMap : nsISupports
* property map (used for passing to to an LDAP search when you want
* everything that could be in a card returned).
*
* @return a comma-separated list of attribute names
* @return an array of attribute names
*
* @exception NS_ERROR_FAILURE there are no attributes in this property map
*/
ACString getAllCardAttributes();
void getAllCardAttributes(out unsigned long aCount,
[retval, array, size_is(aCount)] out string aAttrs);
/**
* Get all properties that may be used in an addressbook card via this

Просмотреть файл

@ -70,6 +70,7 @@ REQUIRES = xpcom \
windowwatcher \
uriloader \
embed_base \
loginmgr \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -119,7 +119,7 @@ nsAbLDAPAttributeMap.prototype = {
return this.mAttrMap[aAttribute];
},
getAllCardAttributes: function getAllCardAttributes() {
getAllCardAttributes: function getAllCardAttributes(aCount) {
var attrs = [];
for each (var prop in this.mPropertyMap) {
attrs.push(prop);
@ -129,7 +129,8 @@ nsAbLDAPAttributeMap.prototype = {
throw Components.results.NS_ERROR_FAILURE;
}
return attrs.join(",");
aCount.value = attrs.length;
return attrs;
},
getAllCardProperties: function getAllCardProperties(aCount) {

Просмотреть файл

@ -210,19 +210,15 @@ NS_IMETHODIMP nsAbLDAPDirectory::HasCard(nsIAbCard* card, PRBool* hasCard)
return NS_OK;
}
NS_IMETHODIMP nsAbLDAPDirectory::GetLDAPURL(nsILDAPURL** url)
NS_IMETHODIMP nsAbLDAPDirectory::GetLDAPURL(nsILDAPURL** aResult)
{
NS_ENSURE_ARG_POINTER(url);
nsresult rv;
nsCOMPtr<nsILDAPURL> result = do_CreateInstance(NS_LDAPURL_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_ARG_POINTER(aResult);
// Rather than using GetURI here we call GetStringValue directly so
// we can handle the case where the URI isn't specified (see comments
// below)
nsCAutoString URI;
rv = GetStringValue("uri", EmptyCString(), URI);
nsresult rv = GetStringValue("uri", EmptyCString(), URI);
if (NS_FAILED(rv) || URI.IsEmpty())
{
/*
@ -243,20 +239,19 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetLDAPURL(nsILDAPURL** url)
* case where it is not a preference, we need to replace the
* "moz-abldapdirectory".
*/
nsCAutoString tempLDAPURL(mURINoQuery);
if (StringBeginsWith(tempLDAPURL, NS_LITERAL_CSTRING(kLDAPDirectoryRoot)))
tempLDAPURL.Replace(0, kLDAPDirectoryRootLen, NS_LITERAL_CSTRING("ldap://"));
URI = mURINoQuery;
if (StringBeginsWith(URI, NS_LITERAL_CSTRING(kLDAPDirectoryRoot)))
URI.Replace(0, kLDAPDirectoryRootLen, NS_LITERAL_CSTRING("ldap://"));
}
rv = result->SetSpec(tempLDAPURL);
}
else
{
rv = result->SetSpec(URI);
}
nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
result.swap(*url);
return rv;
nsCOMPtr<nsIURI> result;
rv = ioService->NewURI(URI, nsnull, nsnull, getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(result, aResult);
}
NS_IMETHODIMP nsAbLDAPDirectory::SetLDAPURL(nsILDAPURL *aUrl)

Просмотреть файл

@ -426,17 +426,15 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::DoQuery(nsIAbDirectory *aDirectory,
}
}
}
// Now formulate the search string
// Get the scope
nsCAutoString scope;
PRBool doSubDirectories;
rv = aArguments->GetQuerySubDirectories (&doSubDirectories);
NS_ENSURE_SUCCESS(rv, rv);
scope = (doSubDirectories) ? "sub" : "one";
// Get the return attributes
nsCOMPtr<nsIURI> uri;
rv = mDirectoryUrl->Clone(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILDAPURL> url(do_QueryInterface(uri, &rv));
NS_ENSURE_SUCCESS(rv, rv);
// Get/Set the return attributes
nsCOMPtr<nsISupports> iSupportsMap;
rv = aArguments->GetTypeSpecificArg(getter_AddRefs(iSupportsMap));
NS_ENSURE_SUCCESS(rv, rv);
@ -445,13 +443,21 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::DoQuery(nsIAbDirectory *aDirectory,
NS_ENSURE_SUCCESS(rv, rv);
// Require all attributes that are mapped to card properties
nsCAutoString returnAttributes;
rv = map->GetAllCardAttributes(returnAttributes);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetAllCardAttributes failed");
PRUint32 returnAttrsCount;
char** returnAttrsArray;
rv = map->GetAllCardAttributes(&returnAttrsCount, &returnAttrsArray);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->SetAttributes(returnAttrsCount,
const_cast<const char**>(returnAttrsArray));
// First free the array
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(returnAttrsCount, returnAttrsArray);
// Now do the error check
NS_ENSURE_SUCCESS(rv, rv);
// Also require the objectClass attribute, it is used by
// nsAbLDAPCard::SetMetaProperties
returnAttributes.AppendLiteral(",objectClass");
rv = url->AddAttribute("objectClass");
// Get the filter
nsCOMPtr<nsISupports> supportsExpression;
@ -479,27 +485,11 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::DoQuery(nsIAbDirectory *aDirectory,
* central to the makeup of the mozilla ldap address book
* entries.
*/
if(filter.IsEmpty())
if (filter.IsEmpty())
{
filter.AssignLiteral("(objectclass=inetorgperson)");
}
nsCAutoString host;
rv = mDirectoryUrl->GetAsciiHost(host);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 port;
rv = mDirectoryUrl->GetPort(&port);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString dn;
rv = mDirectoryUrl->GetDn(dn);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 options;
rv = mDirectoryUrl->GetOptions(&options);
NS_ENSURE_SUCCESS(rv, rv);
// get the directoryFilter from the directory url and merge it with the user's
// search filter
nsCAutoString urlFilter;
@ -532,28 +522,20 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::DoQuery(nsIAbDirectory *aDirectory,
else
searchFilter = filter;
nsCString ldapSearchUrlString;
char* _ldapSearchUrlString =
PR_smprintf("ldap%s://%s:%d/%s?%s?%s?%s",
(options & nsILDAPURL::OPT_SECURE) ? "s" : "",
host.get(),
port,
dn.get(),
returnAttributes.get(),
scope.get(),
searchFilter.get());
if (!_ldapSearchUrlString)
return NS_ERROR_OUT_OF_MEMORY;
ldapSearchUrlString = _ldapSearchUrlString;
PR_smprintf_free(_ldapSearchUrlString);
nsCOMPtr<nsILDAPURL> url;
url = do_CreateInstance(NS_LDAPURL_CONTRACTID, &rv);
rv = url->SetFilter(searchFilter);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->SetSpec(ldapSearchUrlString);
// Now formulate the search string
// Get the scope
PRInt32 scope;
PRBool doSubDirectories;
rv = aArguments->GetQuerySubDirectories (&doSubDirectories);
NS_ENSURE_SUCCESS(rv, rv);
scope = doSubDirectories ? nsILDAPURL::SCOPE_SUBTREE :
nsILDAPURL::SCOPE_ONELEVEL;
rv = url->SetScope(scope);
NS_ENSURE_SUCCESS(rv, rv);
// too soon? Do we need a new listener?

Просмотреть файл

@ -46,8 +46,13 @@
#include "nsIProxyObjectManager.h"
#include "nsILDAPMessage.h"
#include "nsILDAPErrors.h"
#ifdef USE_TK_LOGIN_MANAGER
#include "nsILoginManager.h"
#include "nsILoginInfo.h"
#else
#include "nsCategoryManagerUtils.h"
#include "nsComponentManagerUtils.h"
#endif
#include "nsServiceManagerUtils.h"
#include "nsXPCOMCIDInternal.h"
@ -323,6 +328,44 @@ nsresult nsAbLDAPListenerBase::OnLDAPMessageBind(nsILDAPMessage *aMessage)
if (errCode == nsILDAPErrors::INAPPROPRIATE_AUTH ||
errCode == nsILDAPErrors::INVALID_CREDENTIALS)
{
#ifdef USE_TK_LOGIN_MANAGER
// Login failed, so try again - but first remove the existing login(s)
// so that the user gets prompted. This may not be the best way of doing
// things, we need to review that later.
nsCOMPtr<nsILoginManager> loginMgr =
do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCString spec;
rv = mDirectoryUrl->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
nsCString prePath;
rv = mDirectoryUrl->GetPrePath(prePath);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 count;
nsILoginInfo** logins;
rv = loginMgr->FindLogins(&count, NS_ConvertUTF8toUTF16(prePath),
EmptyString(),
NS_ConvertUTF8toUTF16(spec), &logins);
NS_ENSURE_SUCCESS(rv, rv);
// Typically there should only be one-login stored for this url, however,
// just in case there isn't.
for (PRUint32 i = 0; i < count; ++i)
{
rv = loginMgr->RemoveLogin(logins[i]);
if (NS_FAILED(rv))
{
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
return rv;
}
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
#else
// make sure the wallet service has been created, and in doing so,
// pass in a login-failed message to tell it to forget this passwd.
//
@ -342,7 +385,10 @@ nsresult nsAbLDAPListenerBase::OnLDAPMessageBind(nsILDAPMessage *aMessage)
// this password in the password manager.
return rv;
}
// Login failed, so try again
#endif
// XXX We should probably pop up an error dialog telling
// the user that the login failed here, rather than just bringing
// up the password dialog again, which is what calling OnLDAPInit()

Просмотреть файл

@ -12,12 +12,7 @@ function run_test() {
var abManager = Components.classes["@mozilla.org/abmanager;1"]
.getService(Components.interfaces.nsIAbManager);
var ldapUrl = Components.classes["@mozilla.org/network/ldap-url;1"]
.createInstance(Components.interfaces.nsILDAPURL);
ldapUrl.spec = kLDAPTestSpec;
var abUri = abManager.newAddressBook("test", ldapUrl.spec, kLDAPDirectory);
var abUri = abManager.newAddressBook("test", kLDAPTestSpec, kLDAPDirectory);
// Test - Check we have the directory.
var abDir = abManager.getDirectory(kLDAPUriPrefix + abUri)