git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@188350 18797224-902f-48f8-a5cc-f745e15eee43
684 lines
20 KiB
C++
684 lines
20 KiB
C++
/* -*- 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 ***** */
|
|
|
|
#include "nsLDAPInternal.h"
|
|
#include "nsLDAPMessage.h"
|
|
#include "nspr.h"
|
|
#include "nsDebug.h"
|
|
#include "nsCRT.h"
|
|
#include "nsLDAPConnection.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "nsISupportsUtils.h"
|
|
#include "nsLDAPBERValue.h"
|
|
|
|
|
|
NS_IMPL_THREADSAFE_ADDREF(nsLDAPMessage)
|
|
NS_IMPL_THREADSAFE_RELEASE(nsLDAPMessage)
|
|
NS_INTERFACE_MAP_BEGIN(nsLDAPMessage)
|
|
NS_INTERFACE_MAP_ENTRY(nsILDAPMessage)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILDAPMessage)
|
|
NS_IMPL_QUERY_CLASSINFO(nsLDAPMessage)
|
|
NS_INTERFACE_MAP_END_THREADSAFE
|
|
NS_IMPL_CI_INTERFACE_GETTER1(nsLDAPMessage, nsILDAPMessage)
|
|
|
|
|
|
// constructor
|
|
//
|
|
nsLDAPMessage::nsLDAPMessage()
|
|
: mMsgHandle(0),
|
|
mErrorCode(LDAP_SUCCESS),
|
|
mMatchedDn(0),
|
|
mErrorMessage(0),
|
|
mReferrals(0),
|
|
mServerControls(0)
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
//
|
|
nsLDAPMessage::~nsLDAPMessage(void)
|
|
{
|
|
if (mMsgHandle) {
|
|
int rc = ldap_msgfree(mMsgHandle);
|
|
|
|
// If you are having problems compiling the following code on a Solaris
|
|
// machine with the Forte 6 Update 1 compilers, then you need to make
|
|
// sure you have applied all the required patches. See:
|
|
// http://www.mozilla.org/unix/solaris-build.html for more details.
|
|
|
|
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)
|
|
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
|
|
("nsLDAPMessage::~nsLDAPMessage: ldap_msgfree() "
|
|
"timed out\n"));
|
|
break;
|
|
|
|
default:
|
|
// other failure
|
|
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
|
|
("nsLDAPMessage::~nsLDAPMessage: ldap_msgfree() "
|
|
"failed: %s\n", ldap_err2string(rc)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mMatchedDn) {
|
|
ldap_memfree(mMatchedDn);
|
|
}
|
|
|
|
if (mErrorMessage) {
|
|
ldap_memfree(mErrorMessage);
|
|
}
|
|
|
|
if (mReferrals) {
|
|
ldap_value_free(mReferrals);
|
|
}
|
|
|
|
if (mServerControls) {
|
|
ldap_controls_free(mServerControls);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Initializes a message.
|
|
*
|
|
* @param aConnection The nsLDAPConnection this message is on
|
|
* @param aMsgHandle The native LDAPMessage to be wrapped.
|
|
*
|
|
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
|
|
* @exception NS_ERROR_UNEXPECTED internal err; shouldn't happen
|
|
* @exception NS_ERROR_LDAP_DECODING_ERROR problem during BER decoding
|
|
* @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
|
|
*/
|
|
nsresult
|
|
nsLDAPMessage::Init(nsILDAPConnection *aConnection, LDAPMessage *aMsgHandle)
|
|
{
|
|
int parseResult;
|
|
|
|
if (!aConnection || !aMsgHandle) {
|
|
NS_WARNING("Null pointer passed in to nsLDAPMessage::Init()");
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
}
|
|
|
|
// initialize the appropriate member vars
|
|
//
|
|
mConnection = aConnection;
|
|
mMsgHandle = aMsgHandle;
|
|
|
|
// cache the connection handle. we're violating the XPCOM type-system
|
|
// here since we're a friend of the connection class and in the
|
|
// same module.
|
|
//
|
|
mConnectionHandle = NS_STATIC_CAST(nsLDAPConnection *,
|
|
aConnection)->mConnectionHandle;
|
|
|
|
// do any useful message parsing
|
|
//
|
|
const int msgType = ldap_msgtype(mMsgHandle);
|
|
if ( msgType == -1) {
|
|
NS_ERROR("nsLDAPMessage::Init(): ldap_msgtype() failed");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
switch (msgType) {
|
|
|
|
case LDAP_RES_SEARCH_REFERENCE:
|
|
// XXX should do something here?
|
|
break;
|
|
|
|
case LDAP_RES_SEARCH_ENTRY:
|
|
// nothing to do here
|
|
break;
|
|
|
|
case LDAP_RES_EXTENDED:
|
|
// XXX should do something here?
|
|
break;
|
|
|
|
case LDAP_RES_BIND:
|
|
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:
|
|
parseResult = ldap_parse_result(mConnectionHandle,
|
|
mMsgHandle, &mErrorCode, &mMatchedDn,
|
|
&mErrorMessage,&mReferrals,
|
|
&mServerControls, 0);
|
|
switch (parseResult) {
|
|
case LDAP_SUCCESS:
|
|
// we're good
|
|
break;
|
|
|
|
case LDAP_DECODING_ERROR:
|
|
NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() hit a "
|
|
"decoding error");
|
|
return NS_ERROR_LDAP_DECODING_ERROR;
|
|
|
|
case LDAP_NO_MEMORY:
|
|
NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() ran out "
|
|
"of memory");
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
case LDAP_PARAM_ERROR:
|
|
case LDAP_MORE_RESULTS_TO_RETURN:
|
|
case LDAP_NO_RESULTS_RETURNED:
|
|
default:
|
|
NS_ERROR("nsLDAPMessage::Init(): ldap_parse_result returned "
|
|
"unexpected return code");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
NS_ERROR("nsLDAPMessage::Init(): unexpected message type");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/**
|
|
* The result code of the (possibly partial) operation.
|
|
*
|
|
* @exception NS_ERROR_ILLEGAL_VALUE null pointer passed in
|
|
*
|
|
* readonly attribute long errorCode;
|
|
*/
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetErrorCode(PRInt32 *aErrorCode)
|
|
{
|
|
if (!aErrorCode) {
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
}
|
|
|
|
*aErrorCode = mErrorCode;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetType(PRInt32 *aType)
|
|
{
|
|
if (!aType) {
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
}
|
|
|
|
*aType = ldap_msgtype(mMsgHandle);
|
|
if (*aType == -1) {
|
|
return NS_ERROR_UNEXPECTED;
|
|
};
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// we don't get to use exceptions, so we'll fake it. this is an error
|
|
// handler for IterateAttributes().
|
|
//
|
|
nsresult
|
|
nsLDAPMessage::IterateAttrErrHandler(PRInt32 aLderrno, PRUint32 *aAttrCount,
|
|
char** *aAttributes, BerElement *position)
|
|
{
|
|
|
|
// if necessary, free the position holder used by
|
|
// ldap_{first,next}_attribute()
|
|
//
|
|
if (position) {
|
|
ldap_ber_free(position, 0);
|
|
}
|
|
|
|
// deallocate any entries in the array that have been allocated, then
|
|
// the array itself
|
|
//
|
|
if (*aAttributes) {
|
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(*aAttrCount, *aAttributes);
|
|
}
|
|
|
|
// possibly spit out a debugging message, then return an appropriate
|
|
// error code
|
|
//
|
|
switch (aLderrno) {
|
|
|
|
case LDAP_PARAM_ERROR:
|
|
NS_WARNING("nsLDAPMessage::IterateAttributes() failure; probable bug "
|
|
"or memory corruption encountered");
|
|
return NS_ERROR_UNEXPECTED;
|
|
break;
|
|
|
|
case LDAP_DECODING_ERROR:
|
|
NS_WARNING("nsLDAPMessage::IterateAttributes(): decoding error");
|
|
return NS_ERROR_LDAP_DECODING_ERROR;
|
|
break;
|
|
|
|
case LDAP_NO_MEMORY:
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
break;
|
|
|
|
}
|
|
|
|
NS_WARNING("nsLDAPMessage::IterateAttributes(): LDAP C SDK returned "
|
|
"unexpected value; possible bug or memory corruption");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
|
|
// wrapper for ldap_first_attribute
|
|
//
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetAttributes(PRUint32 *aAttrCount, char** *aAttributes)
|
|
{
|
|
return IterateAttributes(aAttrCount, aAttributes, PR_TRUE);
|
|
}
|
|
|
|
// if getP is PR_TRUE, we get the attributes by recursing once
|
|
// (without getP set) in order to fill in *attrCount, then allocate
|
|
// and fill in the *aAttributes.
|
|
//
|
|
// if getP is PR_FALSE, just fill in *attrCount and return
|
|
//
|
|
nsresult
|
|
nsLDAPMessage::IterateAttributes(PRUint32 *aAttrCount, char** *aAttributes,
|
|
PRBool getP)
|
|
{
|
|
BerElement *position;
|
|
nsresult rv;
|
|
|
|
if (!aAttrCount || !aAttributes ) {
|
|
return NS_ERROR_INVALID_POINTER;
|
|
}
|
|
|
|
// if we've been called from GetAttributes, recurse once in order to
|
|
// count the elements in this message.
|
|
//
|
|
if (getP) {
|
|
*aAttributes = 0;
|
|
*aAttrCount = 0;
|
|
|
|
rv = IterateAttributes(aAttrCount, aAttributes, PR_FALSE);
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
// create an array of the appropriate size
|
|
//
|
|
*aAttributes = NS_STATIC_CAST(char **,
|
|
nsMemory::Alloc(*aAttrCount *
|
|
sizeof(char *)));
|
|
if (!*aAttributes) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
// get the first attribute
|
|
//
|
|
char *attr = ldap_first_attribute(mConnectionHandle,
|
|
mMsgHandle,
|
|
&position);
|
|
if (!attr) {
|
|
return IterateAttrErrHandler(ldap_get_lderrno(mConnectionHandle, 0, 0),
|
|
aAttrCount, aAttributes, position);
|
|
}
|
|
|
|
// if we're getting attributes, try and fill in the first field
|
|
//
|
|
if (getP) {
|
|
(*aAttributes)[0] = nsCRT::strdup(attr);
|
|
if (!(*aAttributes)[0]) {
|
|
ldap_memfree(attr);
|
|
nsMemory::Free(*aAttributes);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// note that we start counting again, in order to keep our place in
|
|
// the array so that we can unwind gracefully and avoid leakage if
|
|
// we hit an error as we're filling in the array
|
|
//
|
|
*aAttrCount = 1;
|
|
} else {
|
|
|
|
// otherwise just update the count
|
|
//
|
|
*aAttrCount = 1;
|
|
}
|
|
ldap_memfree(attr);
|
|
|
|
while (1) {
|
|
|
|
// get the next attribute
|
|
//
|
|
attr = ldap_next_attribute(mConnectionHandle, mMsgHandle, position);
|
|
|
|
// check to see if there is an error, or if we're just done iterating
|
|
//
|
|
if (!attr) {
|
|
|
|
// bail out if there's an error
|
|
//
|
|
PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
|
|
if (lderrno != LDAP_SUCCESS) {
|
|
return IterateAttrErrHandler(lderrno, aAttrCount, aAttributes,
|
|
position);
|
|
}
|
|
|
|
// otherwise, there are no more attributes; we're done with
|
|
// the while loop
|
|
//
|
|
break;
|
|
|
|
} else if (getP) {
|
|
|
|
// if ldap_next_attribute did return successfully, and
|
|
// we're supposed to fill in a value, do so.
|
|
//
|
|
(*aAttributes)[*aAttrCount] = nsCRT::strdup(attr);
|
|
if (!(*aAttributes)[*aAttrCount]) {
|
|
ldap_memfree(attr);
|
|
return IterateAttrErrHandler(LDAP_NO_MEMORY, aAttrCount,
|
|
aAttributes, position);
|
|
}
|
|
|
|
}
|
|
ldap_memfree(attr);
|
|
|
|
// we're done using *aAttrCount as a c-style array index (ie starting
|
|
// at 0). update it to reflect the number of elements now in the array
|
|
//
|
|
*aAttrCount += 1;
|
|
}
|
|
|
|
// free the position pointer, if necessary
|
|
//
|
|
if (position) {
|
|
ldap_ber_free(position, 0);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// readonly attribute wstring dn;
|
|
NS_IMETHODIMP nsLDAPMessage::GetDn(nsACString& aDn)
|
|
{
|
|
char *rawDn = ldap_get_dn(mConnectionHandle, mMsgHandle);
|
|
|
|
if (!rawDn) {
|
|
PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
|
|
|
|
switch (lderrno) {
|
|
|
|
case LDAP_DECODING_ERROR:
|
|
NS_WARNING("nsLDAPMessage::GetDn(): ldap decoding error");
|
|
return NS_ERROR_LDAP_DECODING_ERROR;
|
|
|
|
case LDAP_PARAM_ERROR:
|
|
default:
|
|
NS_ERROR("nsLDAPMessage::GetDn(): internal error");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
}
|
|
|
|
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
|
|
("nsLDAPMessage::GetDn(): dn = '%s'", rawDn));
|
|
|
|
aDn.Assign(rawDn);
|
|
ldap_memfree(rawDn);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// wrapper for ldap_get_values()
|
|
//
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetValues(const char *aAttr, PRUint32 *aCount,
|
|
PRUnichar ***aValues)
|
|
{
|
|
char **values;
|
|
|
|
#if defined(DEBUG)
|
|
// We only want this being logged for debug builds so as not to affect performance too much.
|
|
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
|
|
("nsLDAPMessage::GetValues(): called with aAttr = '%s'", aAttr));
|
|
#endif
|
|
|
|
values = ldap_get_values(mConnectionHandle, mMsgHandle, aAttr);
|
|
|
|
// bail out if there was a problem
|
|
//
|
|
if (!values) {
|
|
PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
|
|
|
|
if ( lderrno == LDAP_DECODING_ERROR ) {
|
|
// this may not be an error; it could just be that the
|
|
// caller has asked for an attribute that doesn't exist.
|
|
//
|
|
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
|
|
("nsLDAPMessage::GetValues(): ldap_get_values returned "
|
|
"LDAP_DECODING_ERROR"));
|
|
return NS_ERROR_LDAP_DECODING_ERROR;
|
|
|
|
} else if ( lderrno == LDAP_PARAM_ERROR ) {
|
|
NS_ERROR("nsLDAPMessage::GetValues(): internal error: 1");
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
} else {
|
|
NS_ERROR("nsLDAPMessage::GetValues(): internal error: 2");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
}
|
|
|
|
// count the values
|
|
//
|
|
PRUint32 numVals = ldap_count_values(values);
|
|
|
|
// create an array of the appropriate size
|
|
//
|
|
*aValues = NS_STATIC_CAST(PRUnichar **,
|
|
nsMemory::Alloc(numVals * sizeof(PRUnichar *)));
|
|
if (!*aValues) {
|
|
ldap_value_free(values);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// clone the array (except for the trailing NULL entry) using the
|
|
// shared allocator for XPCOM correctness
|
|
//
|
|
PRUint32 i;
|
|
for ( i = 0 ; i < numVals ; i++ ) {
|
|
nsDependentCString sValue(values[i]);
|
|
if (IsUTF8(sValue))
|
|
(*aValues)[i] = UTF8ToNewUnicode(sValue);
|
|
else
|
|
(*aValues)[i] = ToNewUnicode(sValue);
|
|
if ( ! (*aValues)[i] ) {
|
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, aValues);
|
|
ldap_value_free(values);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
// now free our value array since we already cloned the values array
|
|
// to the 'aValues' results array.
|
|
ldap_value_free(values);
|
|
|
|
*aCount = numVals;
|
|
return NS_OK;
|
|
}
|
|
|
|
// wrapper for get_values_len
|
|
//
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetBinaryValues(const char *aAttr, PRUint32 *aCount,
|
|
nsILDAPBERValue ***aValues)
|
|
{
|
|
struct berval **values;
|
|
|
|
#if defined(DEBUG)
|
|
// We only want this being logged for debug builds so as not to affect performance too much.
|
|
PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
|
|
("nsLDAPMessage::GetBinaryValues(): called with aAttr = '%s'",
|
|
aAttr));
|
|
#endif
|
|
|
|
values = ldap_get_values_len(mConnectionHandle, mMsgHandle, aAttr);
|
|
|
|
// bail out if there was a problem
|
|
//
|
|
if (!values) {
|
|
PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
|
|
|
|
if ( lderrno == LDAP_DECODING_ERROR ) {
|
|
// this may not be an error; it could just be that the
|
|
// caller has asked for an attribute that doesn't exist.
|
|
//
|
|
PR_LOG(gLDAPLogModule, PR_LOG_WARNING,
|
|
("nsLDAPMessage::GetBinaryValues(): ldap_get_values "
|
|
"returned LDAP_DECODING_ERROR"));
|
|
return NS_ERROR_LDAP_DECODING_ERROR;
|
|
|
|
} else if ( lderrno == LDAP_PARAM_ERROR ) {
|
|
NS_ERROR("nsLDAPMessage::GetBinaryValues(): internal error: 1");
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
} else {
|
|
NS_ERROR("nsLDAPMessage::GetBinaryValues(): internal error: 2");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
}
|
|
|
|
// count the values
|
|
//
|
|
PRUint32 numVals = ldap_count_values_len(values);
|
|
|
|
// create the out array
|
|
//
|
|
*aValues =
|
|
NS_STATIC_CAST(nsILDAPBERValue **,
|
|
nsMemory::Alloc(numVals * sizeof(nsILDAPBERValue)));
|
|
if (!aValues) {
|
|
ldap_value_free_len(values);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// clone the array (except for the trailing NULL entry) using the
|
|
// shared allocator for XPCOM correctness
|
|
//
|
|
PRUint32 i;
|
|
nsresult rv;
|
|
nsCOMPtr<nsILDAPBERValue> berValue;
|
|
for ( i = 0 ; i < numVals ; i++ ) {
|
|
|
|
// create an nsBERValue object
|
|
//
|
|
NS_NEWXPCOM(berValue, nsLDAPBERValue);
|
|
if (!berValue) {
|
|
NS_ERROR("nsLDAPMessage::GetBinaryValues(): out of memory"
|
|
" creating nsLDAPBERValue object");
|
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, aValues);
|
|
ldap_value_free_len(values);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// copy the value from the struct into the nsBERValue
|
|
//
|
|
rv = berValue->Set(values[i]->bv_len,
|
|
NS_REINTERPRET_CAST(PRUint8 *, values[i]->bv_val));
|
|
if (NS_FAILED(rv)) {
|
|
NS_ERROR("nsLDAPMessage::GetBinaryValues(): error setting"
|
|
" nsBERValue");
|
|
ldap_value_free_len(values);
|
|
return rv == NS_ERROR_OUT_OF_MEMORY ? rv : NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
// put the nsIBERValue object into the out array
|
|
//
|
|
NS_ADDREF( (*aValues)[i] = berValue.get() );
|
|
}
|
|
|
|
*aCount = numVals;
|
|
ldap_value_free_len(values);
|
|
return NS_OK;
|
|
}
|
|
|
|
// readonly attribute nsILDAPOperation operation;
|
|
NS_IMETHODIMP nsLDAPMessage::GetOperation(nsILDAPOperation **_retval)
|
|
{
|
|
if (!_retval) {
|
|
NS_ERROR("nsLDAPMessage::GetOperation: null pointer ");
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
NS_IF_ADDREF(*_retval = mOperation);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::ToUnicode(PRUnichar* *aString)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetErrorMessage(nsACString & aErrorMessage)
|
|
{
|
|
aErrorMessage.Assign(mErrorMessage);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsLDAPMessage::GetMatchedDn(nsACString & aMatchedDn)
|
|
{
|
|
aMatchedDn.Assign(mMatchedDn);
|
|
return NS_OK;
|
|
}
|
|
|