initial work to convert nsLDAPOperation, Message, and Connection to implement and use XPCOM interfaces

This commit is contained in:
dmose%mozilla.org 2000-05-17 22:48:50 +00:00
parent fdc1436c42
commit c0800f2ac2
15 changed files with 710 additions and 331 deletions

View File

@ -1,10 +1,5 @@
implementation
--------------
* finish XPCOMifying nsLDAP{Message,Connection,Operation} in order to allow
XPCOM proxies to be used for thread-crossing operations (side benefit: also
exposes more LDAPy goodness to JS) (in progres: dmose)
* make AsyncRead actually be asynchronous (and probably cause ldapSearch.cpp
to be split and moved) by factoring out the lowlevel stuff into another
thread (in progress: dmose)
@ -77,6 +72,20 @@ housecleaning
* investigate the MOZILLA_CLIENT define as used by the SDK. eg do we still
want the reference to "xp_sort.h"?
* does NS_ENSURE_* provide adequate error-checking at interface boundaries
for JS in non-debug builds?
* does always using this-> for member vars cause inheritance problems? if so,
does it matter in an XPCOM world?
* shouldn't be casting results of nsILDAPConnection::GetErrorString to void
in ldapSearch
* finish XPCOMifying nsLDAP{Message,Connection,Operation} and check
thread-safety in order to allow XPCOM proxies to be used for
thread-crossing operations (side benefit: also exposes more LDAPy
goodness to JS)
features
--------

View File

@ -1,3 +1,4 @@
nsILDAPURI.idl
nsILDAPConnection.idl
nsILDAPOperation.idl
nsILDAPMessage.idl

View File

@ -42,6 +42,8 @@ MODULE = mozldap
XPIDL_MODULE = mozldap
XPIDLSRCS = nsILDAPConnection.idl \
nsILDAPOperation.idl \
nsILDAPMessage.idl \
nsILDAPURI.idl \
$(NULL)

View File

@ -33,6 +33,14 @@
#include "nsISupports.idl"
// for the ldapPtr typedef
//
%{C++
#include "ldap.h"
%}
[ptr] native ldapConnectionHandle(LDAP);
[scriptable, uuid(337ad2fe-1dd2-11b2-89f8-aae1221ec86c)]
interface nsILDAPConnection : nsISupports
{
@ -43,6 +51,11 @@ interface nsILDAPConnection : nsISupports
void Init(in string defhost, in short defport);
// wrapper for ldap_get_lderrno()
short GetLdErrno(out string matched, out string s);
long GetLdErrno(out string matched, out string s);
// really only for the internal use of nsLDAPOperation and friends
//
[noscript] readonly attribute ldapConnectionHandle connectionHandle;
};

View File

@ -0,0 +1,79 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the mozilla.org LDAP XPCOM component.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s): Dan Mosedale <dmose@mozilla.org>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsISupports.idl"
#include "nsILDAPOperation.idl"
// for the ldapMsgHandle typedef
//
%{C++
#include "ldap.h"
%}
[ptr] native ldapMsgHandle(LDAPMessage);
[scriptable, uuid(973ff50f-2002-4f0c-b57d-2242156139a2)]
interface nsILDAPMessage : nsISupports
{
// initialize an operation
//
[noscript] void Init(in nsILDAPOperation operation,
in ldapMsgHandle msgHandle);
// wrapper for ldap_get_dn
//
// XXX - currently must use ldap_mem_free to free
//
readonly attribute string DN;
// wrappers for ldap_{first,next}_attribute
//
// XXX - currently must use ldap_mem_free to free the results
//
string firstAttribute();
string nextAttribute();
// wrapper for ldap_get_values
//
// XXX - values must be freed with ldap_value_free
//
void GetValues(in string attr, out unsigned long count,
[retval, array, size_is(count)] out string values);
// turn an error condition associated with this message into an LDAP
// errcode (wrapper around ldap_parse_result)
//
long GetErrorCode();
};

View File

@ -0,0 +1,59 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the mozilla.org LDAP XPCOM component.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s): Dan Mosedale <dmose@mozilla.org>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsISupports.idl"
#include "nsILDAPConnection.idl"
interface nsILDAPMessage;
[scriptable, uuid(fd3d413b-14b0-49c4-8348-a4fc0edba9ff)]
interface nsILDAPOperation : nsISupports
{
// the connection this operation is on
//
attribute nsILDAPConnection connection;
// wrapper for ldap_simple_bind()
//
void SimpleBind(in string binddn, in string passwd);
// wrapper for ldap_search_url()
//
void URLSearch(in string url, in boolean attrsonly);
// wrapper for ldap_result()
// XXX - timeout currently ignored
// XXX - should add consts for all param
//
long Result(in long all, in PRTime timeout, out nsILDAPMessage message);
};

View File

@ -34,40 +34,53 @@
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include "nspr.h"
#include "ldap.h"
#include "nsLDAPConnection.h"
#include "nsLDAPOperation.h"
#include "nsLDAPMessage.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsILDAPConnection.h"
#include "nsILDAPOperation.h"
#include "nsILDAPMessage.h"
#include "nsLDAPChannel.h"
void
NS_METHOD
lds(class nsLDAPChannel *chan, const char *url)
{
class nsLDAPConnection *myConnection;
class nsLDAPMessage *myMessage;
class nsLDAPOperation *myOperation;
struct timeval nullTimeval = {0,0};
// struct timeval timeout = {10,0};
int returnCode;
char *errString;
PRInt16 lden;
nsCOMPtr<nsILDAPConnection> myConnection;
nsCOMPtr<nsILDAPMessage> myMessage;
nsCOMPtr<nsILDAPOperation> myOperation;
int returnCode;
char *errString;
PRInt32 lden;
nsresult rv;
myConnection = new nsLDAPConnection();
if ( !myConnection->Init("nsdirectory.netscape.com", LDAP_PORT) ) {
fprintf(stderr, "main: nsLDAPConnection::Init failed\n");
exit(-1);
}
myOperation = new nsLDAPOperation(myConnection);
// create an LDAP connection
//
myConnection = do_CreateInstance("mozilla.network.ldapconnection", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// initialize it with the defaults
// XXX should return reasonable err msg, not assert
//
rv = myConnection->Init("nsdirectory.netscape.com", LDAP_PORT);
NS_ENSURE_SUCCESS(rv, rv);
// create and initialize an LDAP operation on the new connection
//
myOperation = do_CreateInstance("mozilla.network.ldapoperation", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = myOperation->SetConnection(myConnection);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef NO_URL_SEARCH
fprintf(stderr, "starting bind\n");
fflush(stderr);
if ( !myOperation->SimpleBind(NULL, NULL) ) {
(void)myConnection->GetErrorString(&errString);
fprintf(stderr, "ldap_simple_bind: %s\n", errString);
exit(-1);
return NS_ERROR_FAILURE;
}
fprintf(stderr, "waiting for bind to complete");
@ -92,154 +105,170 @@ lds(class nsLDAPChannel *chan, const char *url)
"myOperation->Result() [myOperation->SimpleBind]: %s: errno=%d\n",
errString, errno);
ldap_memfree(errString);
exit(-1);
return NS_ERROR_FAILURE;
break;
default:
fprintf(stderr, "\nmyOperation->Result() returned unexpected value: %d",
returnCode);
exit(-1);
return NS_ERROR_FAILURE;
}
fprintf(stderr, "bound\n");
delete myMessage;
delete myOperation;
#endif
// start search
fprintf(stderr, "starting search\n");
fflush(stderr);
myOperation = new nsLDAPOperation(myConnection);
// start search
//
PR_fprintf(PR_STDERR, "starting search\n");
// XXX what about timeouts?
//
returnCode = myOperation->URLSearch(url, 0);
if (returnCode == -1) {
exit(-1);
}
myOperation = do_CreateInstance("mozilla.network.ldapoperation", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// poll for results
//
fprintf(stderr, "polling search operation");
returnCode = LDAP_SUCCESS;
while ( returnCode != LDAP_RES_SEARCH_RESULT ) {
rv = myOperation->SetConnection(myConnection);
NS_ENSURE_SUCCESS(rv, rv);
char *dn, *attr;
int rc2;
// XXX what about timeouts?
// XXX failure is a reasonable thing; don't assert
//
rv = myOperation->URLSearch(url, PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
fputc('.', stderr);
// poll for results
//
fprintf(stderr, "polling search operation");
returnCode = LDAP_SUCCESS;
while ( returnCode != LDAP_RES_SEARCH_RESULT ) {
myMessage = new nsLDAPMessage(myOperation);
returnCode = myOperation->Result(LDAP_MSG_ONE, &nullTimeval,
myMessage);
char *dn, *attr;
int rc2;
switch (returnCode) {
case -1: // something went wrong
(void)myConnection->GetErrorString(&errString);
fprintf(stderr,
"\nmyOperation->Result() [URLSearch]: %s: errno=%d\n",
errString, errno);
ldap_memfree(errString);
exit(-1);
case 0: // nothing's been returned yet
break;
fputc('.', stderr);
case LDAP_RES_SEARCH_ENTRY:
fprintf(stderr, "\nentry returned!\n");
// XXX is 0 the right value?
//
rv = myOperation->Result(LDAP_MSG_ONE, (PRTime)0,
getter_AddRefs(myMessage), &returnCode);
// get the DN
dn = myMessage->GetDN();
if (!dn) {
(void)myConnection->GetErrorString(&errString);
fprintf(stderr, "myMessage->GetDN(): %s\n", errString);
exit(-1);
}
chan->pipeWrite("dn: ");
chan->pipeWrite(dn);
chan->pipeWrite("\n");
switch (returnCode) {
case -1: // something went wrong
(void)myConnection->GetErrorString(&errString);
fprintf(stderr,
"\nmyOperation->Result() [URLSearch]: %s: errno=%d\n",
errString, errno);
ldap_memfree(errString);
return NS_ERROR_FAILURE;
case 0: // nothing's been returned yet
break;
ldap_memfree(dn);
case LDAP_RES_SEARCH_ENTRY:
fprintf(stderr, "\nentry returned!\n");
// fetch the attributesget the first attribute
for (attr = myMessage->FirstAttribute();
attr != NULL;
attr = myMessage->NextAttribute()) {
// get the DN
// XXX better err handling
//
rv = myMessage->GetDN(&dn);
NS_ENSURE_SUCCESS(rv, rv);
int i;
char **vals;
chan->pipeWrite("dn: ");
chan->pipeWrite(dn);
chan->pipeWrite("\n");
// get the values of this attribute
vals = myMessage->GetValues(attr);
if (vals == NULL) {
(void)myConnection->GetErrorString(&errString);
fprintf(stderr, "myMessage->GetValues: %s\n", errString);
ldap_memfree(dn);
exit(-1);
}
// fetch the attributes
for (rv = myMessage->FirstAttribute(&attr);
attr != NULL;
rv = myMessage->NextAttribute(&attr)) {
// print all values of this attribute
for ( i=0 ; vals[i] != NULL; i++ ) {
chan->pipeWrite(attr);
chan->pipeWrite(": ");
chan->pipeWrite(vals[i]);
chan->pipeWrite("\n");
}
if ( NS_FAILED(rv) ) {
PR_fprintf(PR_STDERR, "failure getting attribute\n");
return rv;
}
ldap_value_free(vals);
ldap_memfree(attr);
}
int i;
char **vals;
PRUint32 attrCount;
// get the values of this attribute
// XXX better failure handling
//
rv = myMessage->GetValues(attr, &attrCount, &vals);
if (NS_FAILED(rv)) {
(void)myConnection->GetErrorString(&errString);
PR_fprintf(PR_STDERR, "myMessage->GetValues: %s\n",
errString);
return rv;;
}
// print all values of this attribute
for ( i=0 ; vals[i] != NULL; i++ ) {
chan->pipeWrite(attr);
chan->pipeWrite(": ");
chan->pipeWrite(vals[i]);
chan->pipeWrite("\n");
}
ldap_value_free(vals);
ldap_memfree(attr);
}
// did we reach this statement because of an error?
(void)myConnection->GetLdErrno(NULL, NULL, &lden);
if ( lden != LDAP_SUCCESS ) {
// did we reach this statement because of an error?
(void)myConnection->GetLdErrno(NULL, NULL, &lden);
if ( lden != LDAP_SUCCESS ) {
(void)myConnection->GetErrorString(&errString);
fprintf(stderr, "myMessage: error getting attribute: %s\n",
errString);
(void)myConnection->GetErrorString(&errString);
fprintf(stderr, "myMessage: error getting attribute: %s\n",
errString);
return NS_ERROR_FAILURE;
}
exit(-1);
}
// separate this entry from the next
chan->pipeWrite("\n");
// separate this entry from the next
chan->pipeWrite("\n");
// continue polling
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR, "polling search operation");
#endif
break;
// continue polling
fprintf(stderr, "polling search operation");
break;
case LDAP_RES_SEARCH_REFERENCE: // referral
fprintf(stderr,
"LDAP_RES_SEARCH_REFERENCE returned; not implemented!");
return NS_ERROR_FAILURE;
break;
case LDAP_RES_SEARCH_REFERENCE: // referral
fprintf(stderr,
"LDAP_RES_SEARCH_REFERENCE returned; not implemented!");
exit(-1);
break;
case LDAP_RES_SEARCH_RESULT: // all done (the while condition sees this)
fprintf(stderr, "\nresult returned: \n");
case LDAP_RES_SEARCH_RESULT: // all done (the while condition sees this)
fprintf(stderr, "\nresult returned: \n");
rc2 = myMessage->GetErrorCode();
if ( rc2 != LDAP_SUCCESS ) {
fprintf(stderr, " %s\n",
ldap_err2string(rc2));
exit(-1);
}
fprintf(stderr, "success\n");
break;
// XXX should use GetErrorString here?
//
rv = myMessage->GetErrorCode(&rc2);
if ( NS_FAILED(rv) ) {
PR_fprintf(PR_STDERR, " %s\n", ldap_err2string(rc2));
return NS_ERROR_FAILURE;
}
PR_fprintf(PR_STDERR, "success\n");
break;
default:
fprintf(stderr,"unexpected result returned");
exit(-1);
break;
}
default:
PR_fprintf(PR_STDERR, "unexpected result returned");
return NS_ERROR_FAILURE;
break;
}
myMessage = 0;
delete myMessage;
usleep(200);
}
usleep(200);
}
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR,"unbinding\n");
#endif
fprintf(stderr,"unbinding\n");
delete myConnection;
fprintf(stderr,"unbound\n");
myConnection = 0;
#ifdef DEBUG_dmose
PR_fprintf(PR_STDERR,"unbound\n");
#endif
return NS_OK;
}

View File

@ -45,7 +45,7 @@ static NS_DEFINE_CID(kLDAPServiceCID, NS_LDAPSERVICE_CID);
#include "nspr.h"
#endif
void lds(class nsLDAPChannel *chan, const char *);
NS_METHOD lds(class nsLDAPChannel *chan, const char *);
NS_IMPL_ISUPPORTS2(nsLDAPChannel, nsIChannel, nsIRequest);

View File

@ -34,7 +34,7 @@
#include <stdio.h>
#include "nsLDAPConnection.h"
NS_IMPL_ISUPPORTS1(nsLDAPConnection, nsILDAPConnection);
NS_IMPL_THREADSAFE_ISUPPORTS1(nsLDAPConnection, nsILDAPConnection);
// constructor
//
@ -50,7 +50,7 @@ nsLDAPConnection::~nsLDAPConnection()
{
int rc;
rc = ldap_unbind_s(this->connectionHandle);
rc = ldap_unbind_s(this->mConnectionHandle);
if (rc != LDAP_SUCCESS) {
fprintf(stderr, "nsLDAPConnection::~nsLDAPConnection: %s\n",
ldap_err2string(rc));
@ -60,20 +60,26 @@ nsLDAPConnection::~nsLDAPConnection()
// wrapper for ldap_init()
//
NS_IMETHODIMP
nsLDAPConnection::Init(const char *defhost, PRInt16 defport)
nsLDAPConnection::Init(const char *aDefHost, PRInt16 aDefPort)
{
this->connectionHandle = ldap_init(defhost, defport);
return (this->connectionHandle == NULL ? NS_ERROR_FAILURE : NS_OK);
NS_ENSURE_ARG(aDefHost);
NS_ENSURE_ARG(aDefPort);
this->mConnectionHandle = ldap_init(aDefHost, aDefPort);
return (this->mConnectionHandle == NULL ? NS_ERROR_FAILURE : NS_OK);
}
// wrapper for ldap_get_lderrno
//
NS_IMETHODIMP
nsLDAPConnection::GetLdErrno(char **matched, char **errString,
PRInt16 *_retval)
PRInt32 *_retval)
{
*_retval = ldap_get_lderrno(this->connectionHandle, matched, errString);
return NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
*_retval = ldap_get_lderrno(this->mConnectionHandle, matched, errString);
return NS_OK;
}
// return the error string corresponding to GetLdErrno.
@ -84,7 +90,23 @@ nsLDAPConnection::GetLdErrno(char **matched, char **errString,
NS_IMETHODIMP
nsLDAPConnection::GetErrorString(char **_retval)
{
*_retval = ldap_err2string(ldap_get_lderrno(this->connectionHandle,
NULL, NULL));
return NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
*_retval = ldap_err2string(ldap_get_lderrno(this->mConnectionHandle,
NULL, NULL));
return NS_OK;
}
// really only for the internal use of nsLDAPOperation and friends
//
// [ptr] native ldapPtr(LDAP);
// [noscript] readonly attribute ldapPtr connection;
//
NS_IMETHODIMP
nsLDAPConnection::GetConnectionHandle(LDAP* *aConnectionHandle)
{
NS_ENSURE_ARG_POINTER(aConnectionHandle);
*aConnectionHandle = mConnectionHandle;
return NS_OK;
}

View File

@ -37,6 +37,12 @@
#include "nsILDAPConnection.h"
#include "ldap.h"
// 0d871e30-1dd2-11b2-8ea9-831778c78e93
//
#define NS_LDAPCONNECTION_CID \
{ 0x0d871e30, 0x1dd2, 0x11b2, \
{ 0x8e, 0xa9, 0x83, 0x17, 0x78, 0xc7, 0x8e, 0x93 }}
class nsLDAPConnection : public nsILDAPConnection {
friend class nsLDAPOperation;
@ -54,7 +60,7 @@ class nsLDAPConnection : public nsILDAPConnection {
protected:
// the LDAP SDK's struct for the connection
LDAP *connectionHandle;
LDAP *mConnectionHandle;
};

View File

@ -31,15 +31,24 @@
* GPL.
*/
#include "nsLDAPMessage.h"
#include <stdio.h>
#include "nsLDAPMessage.h"
#ifdef DEBUG
#include "nspr.h"
#endif
NS_IMPL_THREADSAFE_ISUPPORTS1(nsLDAPMessage, nsILDAPMessage);
// constructor
nsLDAPMessage::nsLDAPMessage(class nsLDAPOperation *op)
//
nsLDAPMessage::nsLDAPMessage()
{
this->operation = op;
this->message = NULL;
this->position = NULL;
NS_INIT_ISUPPORTS();
mMsgHandle = NULL;
mConnectionHandle = NULL;
mPosition = NULL;
}
// destructor
@ -47,66 +56,94 @@ nsLDAPMessage::nsLDAPMessage(class nsLDAPOperation *op)
//
nsLDAPMessage::~nsLDAPMessage(void)
{
int rc;
int rc;
if (this->message != NULL) {
rc = ldap_msgfree(this->message);
if (mMsgHandle != NULL) {
rc = ldap_msgfree(mMsgHandle);
switch(rc) {
case LDAP_RES_BIND:
case LDAP_RES_SEARCH_ENTRY:
case LDAP_RES_SEARCH_RESULT:
case LDAP_RES_MODIFY:
case LDAP_RES_ADD:
case LDAP_RES_DELETE:
case LDAP_RES_MODRDN:
case LDAP_RES_COMPARE:
case LDAP_RES_SEARCH_REFERENCE:
case LDAP_RES_EXTENDED:
case LDAP_RES_ANY:
// success
break;
case LDAP_SUCCESS:
// timed out (dunno why LDAP_SUCESS is used to indicate this)
fprintf(stderr,
"nsLDAPMessage::~nsLDAPMessage: ldap_msgfree() timed out.\n");
fflush(stderr);
break;
default:
// other failure
// XXX - might errno conceivably be useful here?
fprintf(stderr,"nsLDAPMessage::~nsLDAPMessage: ldap_msgfree: %s\n",
ldap_err2string(rc));
fflush(stderr);
break;
switch(rc) {
case LDAP_RES_BIND:
case LDAP_RES_SEARCH_ENTRY:
case LDAP_RES_SEARCH_RESULT:
case LDAP_RES_MODIFY:
case LDAP_RES_ADD:
case LDAP_RES_DELETE:
case LDAP_RES_MODRDN:
case LDAP_RES_COMPARE:
case LDAP_RES_SEARCH_REFERENCE:
case LDAP_RES_EXTENDED:
case LDAP_RES_ANY:
// success
break;
case LDAP_SUCCESS:
// timed out (dunno why LDAP_SUCCESS is used to indicate this)
fprintf(stderr,
"nsLDAPMessage::~nsLDAPMessage: ldap_msgfree() timed out.\n");
break;
default:
// other failure
// XXX - might errno conceivably be useful here?
fprintf(stderr,"nsLDAPMessage::~nsLDAPMessage: ldap_msgfree: %s\n",
ldap_err2string(rc));
break;
}
}
}
if ( this->position != NULL ) {
ldap_ber_free(this->position, 0);
}
if ( mPosition != NULL ) {
ldap_ber_free(mPosition, 0);
}
}
// associate this message with an existing operation
//
NS_IMETHODIMP
nsLDAPMessage::Init(nsILDAPOperation *aOperation, LDAPMessage *aMsgHandle)
{
nsresult rv;
nsCOMPtr<nsILDAPConnection> connection;
NS_ENSURE_ARG_POINTER(aOperation);
NS_ENSURE_ARG_POINTER(aMsgHandle);
// initialize the appropriate member vars
//
mOperation = aOperation;
mMsgHandle = aMsgHandle;
// cache the connection handle associated with this operation
//
rv = mOperation->GetConnection(getter_AddRefs(connection));
NS_ENSURE_SUCCESS(rv,rv);
rv = connection->GetConnectionHandle(&mConnectionHandle);
NS_ENSURE_SUCCESS(rv,rv);
return NS_OK;
}
// XXX - both this and GetErrorString should be based on a separately
// broken out ldap_parse_result
//
int
nsLDAPMessage::GetErrorCode(void)
NS_IMETHODIMP
nsLDAPMessage::GetErrorCode(PRInt32 *aErrCode)
{
int errcode;
int rc;
PRInt32 rc;
rc = ldap_parse_result(this->operation->connection->connectionHandle,
this->message, &errcode, NULL, NULL,
NULL, NULL, 0);
if (rc != LDAP_SUCCESS) {
fprintf(stderr, "nsLDAPMessage::ErrorToString: ldap_parse_result: %s\n",
ldap_err2string(rc));
exit(-1);
}
rc = ldap_parse_result(mConnectionHandle, mMsgHandle, aErrCode,
NULL, NULL, NULL, NULL, 0);
return(errcode);
if (rc != LDAP_SUCCESS) {
#ifdef DEBUG
PR_fprintf(PR_STDERR,
"nsLDAPMessage::ErrorToString: ldap_parse_result: %s\n",
ldap_err2string(rc));
#endif
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// XXX deal with extra params (make client not have to use ldap_memfree() on
@ -124,9 +161,8 @@ nsLDAPMessage::GetErrorString(void)
int rc;
rc = ldap_parse_result(this->operation->connection->connectionHandle,
this->message, &errcode, &matcheddn, &errmsg,
&referrals, &serverctrls, 0);
rc = ldap_parse_result(mConnectionHandle, mMsgHandle, &errcode, &matcheddn,
&errmsg, &referrals, &serverctrls, 0);
if (rc != LDAP_SUCCESS) {
fprintf(stderr, "nsLDAPMessage::ErrorToString: ldap_parse_result: %s\n",
ldap_err2string(rc));
@ -143,20 +179,34 @@ nsLDAPMessage::GetErrorString(void)
// wrapper for ldap_first_attribute
//
char *
nsLDAPMessage::FirstAttribute(void)
NS_IMETHODIMP
nsLDAPMessage::FirstAttribute(char* *aAttribute)
{
return ldap_first_attribute(this->operation->connection->connectionHandle,
this->message, &(this->position));
NS_ENSURE_ARG_POINTER(aAttribute);
*aAttribute = ldap_first_attribute(mConnectionHandle, mMsgHandle,
&mPosition);
if (*aAttribute) {
return NS_OK;
} else {
return NS_ERROR_FAILURE;
}
}
// wrapper for ldap_next_attribute()
//
char *
nsLDAPMessage::NextAttribute(void)
NS_IMETHODIMP
nsLDAPMessage::NextAttribute(char* *aAttribute)
{
return ldap_next_attribute(this->operation->connection->connectionHandle,
this->message, this->position);
NS_ENSURE_ARG_POINTER(aAttribute);
*aAttribute = ldap_next_attribute(mConnectionHandle, mMsgHandle,
mPosition);
if (*aAttribute) {
return NS_OK;
} else {
return NS_ERROR_FAILURE;
}
}
// wrapper for ldap_msgtype()
@ -164,23 +214,50 @@ nsLDAPMessage::NextAttribute(void)
int
nsLDAPMessage::Type(void)
{
return (ldap_msgtype(this->message));
return (ldap_msgtype(mMsgHandle));
}
// wrapper for ldap_get_dn
//
char *
nsLDAPMessage::GetDN(void)
NS_IMETHODIMP
nsLDAPMessage::GetDN(char* *aDN)
{
return ldap_get_dn(this->operation->connection->connectionHandle,
this->message);
NS_ENSURE_ARG_POINTER(aDN);
*aDN = ldap_get_dn(mConnectionHandle, mMsgHandle);
if (*aDN) {
return NS_OK;
} else {
return NS_ERROR_FAILURE;
}
}
// wrapper for ldap_get_values()
//
char **
nsLDAPMessage::GetValues(const char *attr)
NS_IMETHODIMP
nsLDAPMessage::GetValues(const char *aAttr, PRUint32 *aCount,
char** *aValues)
{
return ldap_get_values(this->operation->connection->connectionHandle,
this->message, attr);
PRUint32 i;
char **values;
values = ldap_get_values(mConnectionHandle, mMsgHandle, aAttr);
// bail out if there was a problem
// XXX - better err handling
//
if (!values) {
return NS_ERROR_FAILURE;
}
// count the values
//
for ( i=0 ; values[i] != NULL; i++ ) {
}
*aCount = i + 1; // include the NULL-terminator in our count
*aValues = values;
return NS_OK;
}

View File

@ -35,45 +35,42 @@
#define _nsLDAPMessage_h_
#include "ldap.h"
#include "nsLDAPOperation.h"
#include "nsILDAPMessage.h"
#include "nsILDAPOperation.h"
#include "nsILDAPConnection.h"
#include "nsCOMPtr.h"
class nsLDAPMessage {
friend class nsLDAPOperation;
// 76e061ad-a59f-43b6-b812-ee6e8e69423f
//
#define NS_LDAPMESSAGE_CID \
{ 0x76e061ad, 0xa59f, 0x43b6, \
{ 0xb8, 0x12, 0xee, 0x6e, 0x8e, 0x69, 0x42, 0x3f }}
public:
class nsLDAPMessage : public nsILDAPMessage
{
friend class nsLDAPOperation;
// constructor
//
nsLDAPMessage(class nsLDAPOperation *op);
public:
// destructor
//
~nsLDAPMessage(void);
NS_DECL_ISUPPORTS;
NS_DECL_NSILDAPMESSAGE;
// turn an error condition associated with this message into an LDAP
// errcode
int GetErrorCode(void);
// constructor & destructor
//
nsLDAPMessage();
virtual ~nsLDAPMessage();
// turn an error condition associated with this message into a string
char *GetErrorString(void);
// turn an error condition associated with this message into a string
char *GetErrorString(void);
// wrapper for ldap_msgtype()
int Type(void);
// wrapper for ldap_msgtype()
int Type(void);
// wrapper for ldap_get_dn()
char *GetDN(void);
// wrapper for ldap_{first,next}_attribute()
char *FirstAttribute(void);
char *NextAttribute(void);
// wrapper for ldap_get_values
char **GetValues(const char *attr);
protected:
LDAPMessage *message; // the message we're wrapping
BerElement *position; // position in the associated attr list
class nsLDAPOperation *operation; // the connection this msg is related to
protected:
LDAPMessage *mMsgHandle; // the message we're wrapping
BerElement *mPosition; // position in the associated attr list
nsCOMPtr<nsILDAPOperation> mOperation; // operation this msg relates to
LDAP *mConnectionHandle; // cached connection handle
};
#endif /* _nsLDAPMessage_h */

View File

@ -33,13 +33,15 @@
#include "ldap.h"
#include "nsLDAPOperation.h"
#include "nsLDAPConnection.h"
#include "nsLDAPMessage.h"
#include "nsILDAPMessage.h"
#include "nsIComponentManager.h"
struct timeval nsLDAPOperation::sNullTimeval = {0, 0};
// constructor
nsLDAPOperation::nsLDAPOperation(class nsLDAPConnection *c)
nsLDAPOperation::nsLDAPOperation()
{
this->connection = c;
NS_INIT_ISUPPORTS();
}
// destructor
@ -47,28 +49,99 @@ nsLDAPOperation::~nsLDAPOperation()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsLDAPOperation, nsILDAPOperation);
// the connection this operation is on
//
// attribute nsILDAPConnection connection;
//
NS_IMETHODIMP
nsLDAPOperation::SetConnection(nsILDAPConnection *aConnection)
{
nsresult rv;
// set the connection
//
mConnection = aConnection;
// get and cache the connection handle
//
rv = this->mConnection->GetConnectionHandle(&this->mConnectionHandle);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
NS_IMETHODIMP
nsLDAPOperation::GetConnection(nsILDAPConnection* *aConnection)
{
NS_ENSURE_ARG_POINTER(aConnection);
*aConnection = mConnection;
NS_IF_ADDREF(*aConnection);
return NS_OK;
}
// wrapper for ldap_simple_bind()
//
bool
NS_IMETHODIMP
nsLDAPOperation::SimpleBind(const char *who, const char *passwd)
{
this->msgId = ldap_simple_bind(this->connection->connectionHandle, who,
passwd);
NS_ENSURE_ARG(who);
NS_ENSURE_ARG(passwd);
if (this->msgId == -1) {
return false;
} else {
return true;
}
this->mMsgId = ldap_simple_bind(this->mConnectionHandle, who,
passwd);
if (this->mMsgId == -1) {
return NS_ERROR_FAILURE;
} else {
return NS_OK;
}
}
// wrapper for ldap_result
int
nsLDAPOperation::Result(int all, struct timeval *timeout,
class nsLDAPMessage *msg)
NS_IMETHODIMP
nsLDAPOperation::Result(PRInt32 aAll,
PRTime timeout,
nsILDAPMessage* *aMessage,
PRInt32 *_retval)
{
return ( ldap_result(this->connection->connectionHandle, this->msgId,
all, timeout, &(msg->message)) );
LDAPMessage *msgHandle;
nsCOMPtr<nsILDAPMessage> msg;
nsresult rv;
NS_ENSURE_ARG_POINTER(aMessage);
NS_ENSURE_ARG_POINTER(_retval);
// make the call
//
*_retval = ldap_result(mConnectionHandle, mMsgId,
aAll, &sNullTimeval, &msgHandle);
// if we didn't error or timeout, create an nsILDAPMessage
//
if (*_retval != 0 && *_retval != -1) {
// create the message
//
msg = do_CreateInstance("mozilla.network.ldapmessage", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// initialize it
//
rv = msg->Init(this, msgHandle);
NS_ENSURE_SUCCESS(rv, rv);
}
*aMessage = msg;
NS_IF_ADDREF(*aMessage);
return NS_OK;
}
// wrappers for ldap_search_ext
@ -84,9 +157,9 @@ nsLDAPOperation::SearchExt(const char *base, // base DN to search
struct timeval *timeoutp, // how long to wait
int sizelimit) // max # of entries to return
{
return ldap_search_ext(this->connection->connectionHandle, base, scope,
return ldap_search_ext(this->mConnectionHandle, base, scope,
filter, attrs, attrsOnly, serverctrls,
clientctrls, timeoutp, sizelimit, &(this->msgId));
clientctrls, timeoutp, sizelimit, &(this->mMsgId));
}
int
@ -97,16 +170,22 @@ nsLDAPOperation::SearchExt(const char *base, // base DN to search
int sizelimit) // max # of entries to return
{
return nsLDAPOperation::SearchExt(base, scope, filter, NULL, 0, NULL,
NULL, timeoutp, sizelimit);
NULL, timeoutp, sizelimit);
}
// wrapper for ldap_url_search
//
int
nsLDAPOperation::URLSearch(const char *URL, // the search URL
int attrsonly) // skip attribute names?
NS_IMETHODIMP
nsLDAPOperation::URLSearch(const char *aURL, // the search URL
PRBool aAttrsOnly) // skip attribute names?
{
this->msgId = ldap_url_search(this->connection->connectionHandle, URL,
attrsonly);
return this->msgId;
NS_ENSURE_ARG(aURL);
this->mMsgId = ldap_url_search(this->mConnectionHandle, aURL,
aAttrsOnly);
if (this->mMsgId == -1) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@ -35,55 +35,50 @@
#define _nsLDAPOperation_h_
#include "ldap.h"
#include "nsLDAPConnection.h"
#include "nsCOMPtr.h"
#include "nsILDAPConnection.h"
#include "nsILDAPOperation.h"
class nsLDAPOperation {
// 97a479d0-9a44-47c6-a17a-87f9b00294bb
#define NS_LDAPOPERATION_CID \
{ 0x97a479d0, 0x9a44, 0x47c6, \
{ 0xa1, 0x7a, 0x87, 0xf9, 0xb0, 0x02, 0x94, 0xbb}}
friend class nsLDAPMessage;
class nsLDAPOperation : public nsILDAPOperation
{
public:
public:
NS_DECL_ISUPPORTS;
NS_DECL_NSILDAPOPERATION;
// constructor
//
nsLDAPOperation(class nsLDAPConnection *c);
// constructor & destructor
//
nsLDAPOperation();
virtual ~nsLDAPOperation();
// destructor
//
~nsLDAPOperation();
// wrappers for ldap_search_ext
//
int SearchExt(const char *base, // base DN to search
int scope, // LDAP_SCOPE_{BASE,ONELEVEL,SUBTREE}
const char* filter, // search filter
char **attrs, // attribute types to be returned
int attrsOnly, // attrs only, or values too?
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeoutp, // how long to wait
int sizelimit); // max # of entries to return
// wrapper for ldap_simple_bind()
//
bool SimpleBind(const char *who, const char *passwd);
// wrapper for ldap_result()
// XXX - should this really be part of the nsLDAPMessage class?
int Result(int all, struct timeval *timeout, class nsLDAPMessage *m);
int SearchExt(const char *base, // base DN to search
int scope, // LDAP_SCOPE_{BASE,ONELEVEL,SUBTREE}
const char* filter, // search filter
struct timeval *timeoutp, // how long to wait
int sizelimit); // max # of entries to return
// wrappers for ldap_search_ext
//
int SearchExt(const char *base, // base DN to search
int scope, // LDAP_SCOPE_{BASE,ONELEVEL,SUBTREE}
const char* filter, // search filter
char **attrs, // attribute types to be returned
int attrsOnly, // attrs only, or values too?
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeoutp, // how long to wait
int sizelimit); // max # of entries to return
int SearchExt(const char *base, // base DN to search
int scope, // LDAP_SCOPE_{BASE,ONELEVEL,SUBTREE}
const char* filter, // search filter
struct timeval *timeoutp, // how long to wait
int sizelimit); // max # of entries to return
// wrapper for ldap_search_url. returns msg id #; -1 is an error.
//
int URLSearch(const char *URL, // the URL to search
int attrsonly); // skip the attr names?
protected:
int msgId;
class nsLDAPConnection *connection; // connection this op is happening on.
protected:
PRInt32 mMsgId;
nsCOMPtr<nsILDAPConnection> mConnection;
LDAP *mConnectionHandle; // cached from mConnection->GetConnectionHandle()
static struct timeval sNullTimeval;
};
#endif /* _nsLDAPOperation_h */

View File

@ -35,22 +35,33 @@
#include "nsLDAPProtocolHandler.h"
#include "nsLDAPChannel.h"
#include "nsLDAPService.h"
#include "nsLDAPConnection.h"
#include "nsLDAPOperation.h"
#include "nsLDAPMessage.h"
// use the default constructor
//
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPProtocolHandler);
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLDAPService, Init);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPConnection);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPOperation);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPMessage);
// a table of the CIDs implemented by this module (in this case, just one)
//
static nsModuleComponentInfo components[] =
{
{ "LDAP Protocol Handler", NS_LDAPPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_PROGID_PREFIX "ldap", nsLDAPProtocolHandlerConstructor
},
{ "LDAP Service", NS_LDAPSERVICE_CID,
"mozilla.network.ldapservice", nsLDAPServiceConstructor
}
{ "LDAP Protocol Handler", NS_LDAPPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_PROGID_PREFIX "ldap",
nsLDAPProtocolHandlerConstructor },
{ "LDAP Service", NS_LDAPSERVICE_CID, "mozilla.network.ldapservice",
nsLDAPServiceConstructor },
{ "LDAP Connection", NS_LDAPCONNECTION_CID,
"mozilla.network.ldapconnection", nsLDAPConnectionConstructor },
{ "LDAP Operation", NS_LDAPOPERATION_CID,
"mozilla.network.ldapoperation", nsLDAPOperationConstructor },
{ "LDAP Message", NS_LDAPMESSAGE_CID,
"mozilla.network.ldapmessage", nsLDAPMessageConstructor }
};
// implement the NSGetModule() exported function