--- a/directory/xpcom/Makefile.in
+++ b/directory/xpcom/Makefile.in
@@ -38,27 +38,24 @@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
-# Note that for the time being "tests" require LDAP Experimental
-#
DIRS = \
base \
$(NULL)
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
DIRS += \
datasource \
$(NULL)
+endif
ifdef ENABLE_TESTS
DIRS += \
tests
endif
-endif
-
include $(topsrcdir)/config/rules.mk
--- a/directory/xpcom/base/public/nsILDAPURL.idl
+++ b/directory/xpcom/base/public/nsILDAPURL.idl
@@ -47,18 +47,43 @@
/**
* Strings in methods inherited from nsIURI, which are using XPIDL
* |string| types, are expected to be UTF8 encoded. All such strings
* in this interface, except attribute types (e.g. "cn"), should in fact
* be UTF8. It's important to remember that attributes can not be UTF8,
* 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).
* This string is expected to be a valid UTF8 string.
*
* for the getter:
*
* @exception NS_ERROR_NULL_POINTER NULL pointer to GET method
@@ -146,10 +171,9 @@ interface nsILDAPURL : nsIURI {
* @exception NS_ERROR_OUT_OF_MEMORY Ran out of memory
*/
attribute unsigned long options;
/**
* If this is set/true, this is an ldaps: URL, not an ldap: URL
*/
const unsigned long OPT_SECURE = 0x01;
-
};
--- a/directory/xpcom/base/src/Makefile.in
+++ b/directory/xpcom/base/src/Makefile.in
@@ -51,30 +51,32 @@ IS_COMPONENT = 1
MODULE_NAME = nsLDAPProtocolModule
MOZILLA_INTERNAL_API = 1
REQUIRES = xpcom \
string \
necko \
$(NULL)
+EXTRA_PP_COMPONENTS = \
+ nsLDAPProtocolHandler.js \
+ $(NULL)
CPPSRCS = \
nsLDAPProtocolModule.cpp \
nsLDAPMessage.cpp \
nsLDAPConnection.cpp \
nsLDAPOperation.cpp \
nsLDAPURL.cpp \
nsLDAPServer.cpp \
nsLDAPService.cpp \
nsLDAPBERValue.cpp \
nsLDAPControl.cpp \
nsLDAPBERElement.cpp \
nsLDAPModification.cpp \
- nsLDAPProtocolHandler.cpp \
$(NULL)
ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
DEFINES += -DMOZ_LDAP_XPCOM_EXPERIMENTAL
CPPSRCS += \
nsLDAPChannel.cpp \
$(NULL)
--- a/directory/xpcom/base/src/nsLDAPChannel.h
+++ b/directory/xpcom/base/src/nsLDAPChannel.h
@@ -57,16 +57,21 @@
#include "nsILDAPURL.h"
// if the code related to the following #define ever gets removed, also
// be sure to remove mCallback as well as the most (but not all) of the
// various mUnproxied stuff
//
#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:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSILDAPMESSAGELISTENER
deleted file mode 100644
--- a/directory/xpcom/base/src/nsLDAPProtocolHandler.cpp
+++ /dev/null
@@ -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;
-}
-
deleted file mode 100644
--- a/directory/xpcom/base/src/nsLDAPProtocolHandler.h
+++ /dev/null
@@ -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__
new file mode 100644
--- /dev/null
+++ b/directory/xpcom/base/src/nsLDAPProtocolHandler.js
@@ -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]);
+}
--- a/directory/xpcom/base/src/nsLDAPProtocolModule.cpp
+++ b/directory/xpcom/base/src/nsLDAPProtocolModule.cpp
@@ -47,37 +47,38 @@
#include "nsLDAPOperation.h"
#include "nsLDAPMessage.h"
#include "nsLDAPModification.h"
#include "nsLDAPServer.h"
#include "nsLDAPService.h"
#include "nsLDAPBERValue.h"
#include "nsLDAPBERElement.h"
#include "nsLDAPControl.h"
-#include "nsLDAPProtocolHandler.h"
#include "ldappr.h"
#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
#include "nsLDAPChannel.h"
#endif
// use the default constructor
//
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPConnection)
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)
NS_DECL_CLASSINFO(nsLDAPConnection)
// a table of the CIDs implemented by this module
//
static const nsModuleComponentInfo components[] =
@@ -110,25 +111,26 @@ static const nsModuleComponentInfo compo
&NS_CLASSINFO_NAME(nsLDAPMessage),
nsIClassInfo::THREADSAFE },
{ "LDAP Modification", NS_LDAPMODIFICATION_CID,
"@mozilla.org/network/ldap-modification;1", nsLDAPModificationConstructor },
{ "LDAP Server", NS_LDAPSERVER_CID,
"@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}
};
static nsresult
nsLDAPInitialize(nsIModule *aSelf)
{
#ifdef PR_LOGGING
--- a/directory/xpcom/base/src/nsLDAPURL.cpp
+++ b/directory/xpcom/base/src/nsLDAPURL.cpp
@@ -38,339 +38,367 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsLDAPURL.h"
#include "nsReadableUtils.h"
#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 (!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)
{
- if (!mAttributes) {
- mAttributes = new nsCStringArray();
- if (!mAttributes) {
- NS_ERROR("nsLDAPURL::Init: out of memory ");
- return NS_ERROR_OUT_OF_MEMORY;
- }
+ 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 ((count = mAttributes->Count())) {
- PRUint32 index = 0;
+ if (!mBaseURL)
+ return NS_ERROR_NOT_INITIALIZED;
- spec.Append('?');
- while (index < count) {
- spec.Append(*(mAttributes->CStringAt(index++)));
- if (index < count) {
- spec.Append(',');
- }
- }
- }
+ return mBaseURL->GetSpec(_retval);
+}
- 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;
-}
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;
-
- case LDAP_URL_ERR_NOTLDAP:
- case LDAP_URL_ERR_NODN:
- case LDAP_URL_ERR_BADSCOPE:
- return NS_ERROR_MALFORMED_URI;
+ rv = SetPathInternal(nsPromiseFlatCString(aSpec));
+ if (NS_FAILED(rv))
+ mBaseURL->SetSpec(originalSpec);
- 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;
}
-// attribute string username
-//
+NS_IMETHODIMP
+nsLDAPURL::SetUserPass(const nsACString &aUserPass)
+{
+ return NS_OK;
+}
+
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 mBaseURL->GetHostPort(_retval);
+}
- return NS_OK;
-}
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);
}
-// attribute string specA
+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);
+}
+
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)
// (based on nsSimpleURI::Equals)
NS_IMETHODIMP nsLDAPURL::Equals(nsIURI *other, PRBool *_retval)
{
*_retval = PR_FALSE;
if (other)
@@ -395,211 +423,261 @@ NS_IMETHODIMP nsLDAPURL::Equals(nsIURI *
*_retval = PR_TRUE;
}
}
return NS_OK;
}
// 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);
//
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
// attribute AUTF8String dn;
//
NS_IMETHODIMP nsLDAPURL::GetDn(nsACString& _retval)
{
_retval.Assign(mDN);
return NS_OK;
}
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,
// [array, size_is (aCount), retval] out string aAttrs);
//
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;
if (!_retval) {
NS_ERROR("nsLDAPURL::GetAttributes: null pointer ");
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) {
NS_ERROR("nsLDAPURL::GetAttributes: out of memory ");
return NS_ERROR_OUT_OF_MEMORY;
}
// 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;
}
index++;
}
}
*aCount = count;
*_retval = cArray;
return NS_OK;
}
// void setAttributes (in unsigned long aCount,
// [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;
+
+ 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;
}
+ }
- return NS_OK;
+ // 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;
+
+ NS_ENSURE_ARG_POINTER(aAttribute);
- str = nsDependentCString(aAttribute);
- if (mAttributes->IndexOfIgnoreCase(str) >= 0) {
- return NS_OK;
- }
+ nsDependentCString str(aAttribute);
+
+ if (mAttributes.IndexOfIgnoreCase(str) >= 0)
+ return NS_OK;
- if (!mAttributes->InsertCStringAt(str, mAttributes->Count())) {
- NS_ERROR("nsLDAPURL::AddAttribute: out of memory ");
- return NS_ERROR_OUT_OF_MEMORY;
- }
+ if (!mAttributes.AppendCString(str)) {
+ NS_ERROR("nsLDAPURL::AddAttribute: out of memory ");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
- return NS_OK;
+ // 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;
- }
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = mScope;
+ return NS_OK;
+}
- *_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;
+
+ // Only allow scopes supported by the C-SDK
+ if ((aScope != SCOPE_BASE) && (aScope != SCOPE_ONELEVEL) &&
+ (aScope != SCOPE_SUBTREE))
+ return NS_ERROR_MALFORMED_URI;
- mScope = aScope;
+ mScope = aScope;
- return NS_OK;
+ // 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);
return NS_OK;
}
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;
- }
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = mOptions;
+ return NS_OK;
+}
- *_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);
}
--- a/directory/xpcom/base/src/nsLDAPURL.h
+++ b/directory/xpcom/base/src/nsLDAPURL.h
@@ -1,9 +1,9 @@
-/* -*- 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
*
* 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/
@@ -37,34 +37,52 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap.h"
#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:
- 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
+ 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;
};
--- a/directory/xpcom/tests/Makefile.in
+++ b/directory/xpcom/tests/Makefile.in
@@ -38,27 +38,37 @@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
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
RUN = cmd /c start
else
RUN = $(DIST)/bin/run-mozilla.sh
endif
XPCSHELL = $(DIST)/bin/xpcshell
.PHONY: ldapshell
ldapshell:
$(CYGWIN_WRAPPER) $(RUN) $(XPCSHELL) \
-f $(srcdir)/ldapshell.js \
-f -
+endif
--- a/directory/xpcom/tests/jar.mn
+++ b/directory/xpcom/tests/jar.mn
@@ -1,3 +1,5 @@
+#ifdef MOZ_LDAP_XPCOM_EXPERIMENTAL
comm.jar:
content/communicator/ldapviewer/example.xul
content/communicator/ldapviewer/example.rdf
+#endif
new file mode 100644
--- /dev/null
+++ b/directory/xpcom/tests/unit/test_nsLDAPURL.js
@@ -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=*)");
+}
--- a/mailnews/addrbook/prefs/resources/content/pref-directory-add.js
+++ b/mailnews/addrbook/prefs/resources/content/pref-directory-add.js
@@ -183,32 +183,38 @@ function fillSettings()
document.getElementById("description").value = gCurrentDirectory.dirName;
if (gCurrentDirectory instanceof Components.interfaces.nsIAbLDAPDirectory) {
var ldapUrl = gCurrentDirectory.lDAPURL;
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;
var sub = document.getElementById("sub");
switch(ldapUrl.scope) {
case Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL:
sub.radioGroup.selectedItem = document.getElementById("one");
break;
default:
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.
//If they are locked disable them
DisableUriFields(gCurrentDirectory.dirPrefId + ".uri");
DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".description", "description");
DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".disable_button_download", "download");
DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".maxHits", "results");
@@ -280,59 +286,55 @@ function onAccept()
{
var addressbook = Components.classes["@mozilla.org/abmanager;1"]
.getService(Components.interfaces.nsIAbManager);
try {
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;
var secure = document.getElementById("secure");
var results = document.getElementById("results").value;
var errorValue = null;
if ((!description) || hasOnlyWhitespaces(description))
errorValue = "invalidName";
else if ((!hostname) || hasOnlyWhitespaces(hostname))
errorValue = "invalidHostname";
// XXX write isValidDn and call it on the dn string here?
else if (port && hasCharacters(port))
errorValue = "invalidPortNumber";
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
window.opener.gNewServerString =
addressbook.newAddressBook(description, ldapUrl.spec, kLDAPDirectory);
}
// the rdf service
--- a/mailnews/addrbook/public/nsIAbLDAPAttributeMap.idl
+++ b/mailnews/addrbook/public/nsIAbLDAPAttributeMap.idl
@@ -62,17 +62,17 @@ interface nsIAbCard;
* property. The checkState method is a useful tool in enforcing
* this. Failure to enforce it may make it impossible to guarantee
* that getProperty will do something consistent and reasonable.
*
* Maybe someday once we support ldap autoconfig stuff (ie
* 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
{
/**
* Get all the LDAP attributes associated with a given property
* name, in order of precedence (highest to lowest).
*
* @param aProperty the address book property to return attrs for
*
@@ -134,21 +134,22 @@ interface nsIAbLDAPAttributeMap : nsISup
*/
ACString getProperty(in ACString aAttribute);
/**
* Get all attributes that may be used in an addressbook card via this
* 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
* property map.
*
* @return an array of properties
*
* @exception NS_ERROR_FAILURE there are no attributes in this property map
--- a/mailnews/addrbook/src/Makefile.in
+++ b/mailnews/addrbook/src/Makefile.in
@@ -65,16 +65,17 @@ REQUIRES = xpcom \
uconv \
msgbase \
msgbaseutil \
mime \
intl \
windowwatcher \
uriloader \
embed_base \
+ loginmgr \
$(NULL)
CPPSRCS = \
nsAbManager.cpp \
nsAbRDFDataSource.cpp \
nsDirectoryDataSource.cpp \
nsAbCardProperty.cpp \
nsDirPrefs.cpp \
--- a/mailnews/addrbook/src/nsAbLDAPAttributeMap.js
+++ b/mailnews/addrbook/src/nsAbLDAPAttributeMap.js
@@ -114,27 +114,28 @@ nsAbLDAPAttributeMap.prototype = {
if (!(aAttribute in this.mAttrMap)) {
return null;
}
return this.mAttrMap[aAttribute];
},
- getAllCardAttributes: function getAllCardAttributes() {
+ getAllCardAttributes: function getAllCardAttributes(aCount) {
var attrs = [];
for each (var prop in this.mPropertyMap) {
attrs.push(prop);
}
if (!attrs.length) {
throw Components.results.NS_ERROR_FAILURE;
}
- return attrs.join(",");
+ aCount.value = attrs.length;
+ return attrs;
},
getAllCardProperties: function getAllCardProperties(aCount) {
var props = [];
for (var prop in this.mPropertyMap) {
props.push(prop);
}
--- a/mailnews/addrbook/src/nsAbLDAPDirectory.cpp
+++ b/mailnews/addrbook/src/nsAbLDAPDirectory.cpp
@@ -205,29 +205,25 @@ NS_IMETHODIMP nsAbLDAPDirectory::HasCard
*hasCard = mCache.Get(card, nsnull);
if (!*hasCard && mPerformingQuery)
return NS_ERROR_NOT_AVAILABLE;
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())
{
/*
* A recent change in Mozilla now means that the LDAP Address Book
* RDF Resource URI is based on the unique preference name value i.e.
* [moz-abldapdirectory://prefName]
* Prior to this valid change it was based on the actual uri i.e.
* [moz-abldapdirectory://host:port/basedn]
@@ -238,30 +234,29 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetLDAP
* products could integrate with Mozilla's LDAP Address Books
* without necessarily having an entry in the preferences file
* or more importantly needing to be able to change the
* preferences entries. Thus to set the URI Spec now, it is
* only necessary to read the uri pref entry, while in the
* 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)
{
NS_ENSURE_ARG_POINTER(aUrl);
nsCAutoString oldUrl;
// Note, it doesn't matter if GetStringValue fails - we'll just send an
--- a/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp
+++ b/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp
@@ -421,42 +421,48 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::Do
if (login != mCurrentLogin || protocolVersion != mCurrentProtocolVersion)
{
redoConnection = PR_TRUE;
mCurrentLogin = login;
mCurrentProtocolVersion = protocolVersion;
}
}
}
-
- // Now formulate the search string
-
- // Get the scope
- nsCAutoString scope;
- PRBool doSubDirectories;
- rv = aArguments->GetQuerySubDirectories (&doSubDirectories);
+
+ nsCOMPtr<nsIURI> uri;
+ rv = mDirectoryUrl->Clone(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
- scope = (doSubDirectories) ? "sub" : "one";
- // Get the return attributes
+ 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);
nsCOMPtr<nsIAbLDAPAttributeMap> map = do_QueryInterface(iSupportsMap, &rv);
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;
rv = aArguments->GetExpression (getter_AddRefs (supportsExpression));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAbBooleanExpression> expression (do_QueryInterface (supportsExpression, &rv));
nsCAutoString filter;
@@ -474,37 +480,21 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::Do
*
* Default the filter string if blank, otherwise it gets
* set to (objectclass=*) which returns everything. Set
* the default to (objectclass=inetorgperson) as this
* is the most appropriate default objectclass which is
* 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;
rv = mDirectoryUrl->GetFilter(urlFilter);
// if urlFilter is unset (or set to the default "objectclass=*"), there's
// no need to AND in an empty search term, so leave prefix and suffix empty
@@ -527,38 +517,30 @@ NS_IMETHODIMP nsAbLDAPDirectoryQuery::Do
}
searchFilter += filter;
searchFilter += ')';
}
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?
// If we already have a connection, and don't need to re-do it, give it the
// new search details and go for it...
if (!redoConnection)
{
nsAbQueryLDAPMessageListener *msgListener =
--- a/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp
+++ b/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp
@@ -41,18 +41,23 @@
#include "nsAbLDAPListenerBase.h"
#include "nsIWindowWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIAuthPrompt.h"
#include "nsIStringBundle.h"
#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"
nsAbLDAPListenerBase::nsAbLDAPListenerBase(nsILDAPURL* url,
nsILDAPConnection* connection,
const nsACString &login,
const PRInt32 timeOut) :
mDirectoryUrl(url), mConnection(connection), mLogin(login),
@@ -318,16 +323,54 @@ nsresult nsAbLDAPListenerBase::OnLDAPMes
if (errCode != nsILDAPErrors::SUCCESS)
{
// if the login failed, tell the wallet to forget this password
//
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.
//
// apparently getting passwords stored in the wallet
// doesn't require the service to be running, which is why
// this might not exist yet.
//
rv = NS_CreateServicesFromCategory("passwordmanager",
@@ -337,17 +380,20 @@ nsresult nsAbLDAPListenerBase::OnLDAPMes
{
NS_ERROR("nsLDAPAutoCompleteSession::ForgetPassword(): error"
" creating password manager service");
// not much to do at this point, though conceivably we could
// pop up a dialog telling the user to go manually delete
// 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()
// does.
return OnLDAPInit(nsnull, NS_OK);
}
// Don't know how to handle this, so use the message error code in
--- a/mailnews/addrbook/test/unit/test_ldap1.js
+++ b/mailnews/addrbook/test/unit/test_ldap1.js
@@ -7,22 +7,17 @@ const kLDAPDirectory = 0; // defined in
const kLDAPUriPrefix = "moz-abldapdirectory://";
const kLDAPTestSpec = "ldap://invalidhost:389//dc=intranet??sub?(objectclass=*)";
function run_test() {
// Test - Create an LDAP directory
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)
.QueryInterface(Components.interfaces.nsIAbLDAPDirectory);
// Test - Check various fields
do_check_eq(abDir.dirName, "test");
do_check_eq(abDir.lDAPURL.spec, kLDAPTestSpec);