Mercurial > trustbridge > nss-cmake-static
view nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c @ 3:150b72113545
Add DBM and legacydb support
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 05 Aug 2014 18:32:02 +0200 |
parents | 1e5118fa0cb1 |
children |
line wrap: on
line source
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * pkix_pl_ldaprequest.c * */ #include "pkix_pl_ldaprequest.h" /* --Private-LdapRequest-Functions------------------------------------- */ /* Note: lengths do not include the NULL terminator */ static const char caAttr[] = "caCertificate;binary"; static unsigned int caAttrLen = sizeof(caAttr) - 1; static const char uAttr[] = "userCertificate;binary"; static unsigned int uAttrLen = sizeof(uAttr) - 1; static const char ccpAttr[] = "crossCertificatePair;binary"; static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1; static const char crlAttr[] = "certificateRevocationList;binary"; static unsigned int crlAttrLen = sizeof(crlAttr) - 1; static const char arlAttr[] = "authorityRevocationList;binary"; static unsigned int arlAttrLen = sizeof(arlAttr) - 1; /* * XXX If this function were moved into pkix_pl_ldapcertstore.c then all of * LdapRequest and LdapResponse could be considered part of the LDAP client. * But the constants, above, would have to be copied as well, and they are * also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be * two copies. */ /* * FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit * DESCRIPTION: * * This function creates an attribute mask bit corresponding to the SECItem * pointed to by "attrType", storing the result at "pAttrBit". The comparison * is case-insensitive. If "attrType" does not match any of the known types, * zero is stored at "pAttrBit". * * PARAMETERS * "attrType" * The address of the SECItem whose string contents are to be compared to * the various known attribute types. Must be non-NULL. * "pAttrBit" * The address where the result is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an LdapRequest Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapRequest_AttrTypeToBit( SECItem *attrType, LdapAttrMask *pAttrBit, void *plContext) { LdapAttrMask attrBit = 0; unsigned int attrLen = 0; const char *s = NULL; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit"); PKIX_NULLCHECK_TWO(attrType, pAttrBit); s = (const char *)attrType->data; attrLen = attrType->len; /* * Taking note of the fact that all of the comparand strings are * different lengths, we do a slight optimization. If a string * length matches but the string does not match, we skip comparing * to the other strings. If new strings are added to the comparand * list, and any are of equal length, be careful to change the * grouping of tests accordingly. */ if (attrLen == caAttrLen) { if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) { attrBit = LDAPATTR_CACERT; } } else if (attrLen == uAttrLen) { if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) { attrBit = LDAPATTR_USERCERT; } } else if (attrLen == ccpAttrLen) { if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) { attrBit = LDAPATTR_CROSSPAIRCERT; } } else if (attrLen == crlAttrLen) { if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) { attrBit = LDAPATTR_CERTREVLIST; } } else if (attrLen == arlAttrLen) { if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) { attrBit = LDAPATTR_AUTHREVLIST; } } *pAttrBit = attrBit; PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_AttrStringToBit * DESCRIPTION: * * This function creates an attribute mask bit corresponding to the null- * terminated string pointed to by "attrString", storing the result at * "pAttrBit". The comparison is case-insensitive. If "attrString" does not * match any of the known types, zero is stored at "pAttrBit". * * PARAMETERS * "attrString" * The address of the null-terminated string whose contents are to be compared to * the various known attribute types. Must be non-NULL. * "pAttrBit" * The address where the result is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an LdapRequest Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapRequest_AttrStringToBit( char *attrString, LdapAttrMask *pAttrBit, void *plContext) { LdapAttrMask attrBit = 0; unsigned int attrLen = 0; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit"); PKIX_NULLCHECK_TWO(attrString, pAttrBit); attrLen = PL_strlen(attrString); /* * Taking note of the fact that all of the comparand strings are * different lengths, we do a slight optimization. If a string * length matches but the string does not match, we skip comparing * to the other strings. If new strings are added to the comparand * list, and any are of equal length, be careful to change the * grouping of tests accordingly. */ if (attrLen == caAttrLen) { if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) { attrBit = LDAPATTR_CACERT; } } else if (attrLen == uAttrLen) { if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) { attrBit = LDAPATTR_USERCERT; } } else if (attrLen == ccpAttrLen) { if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) { attrBit = LDAPATTR_CROSSPAIRCERT; } } else if (attrLen == crlAttrLen) { if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) { attrBit = LDAPATTR_CERTREVLIST; } } else if (attrLen == arlAttrLen) { if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) { attrBit = LDAPATTR_AUTHREVLIST; } } *pAttrBit = attrBit; PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_EncodeAttrs * DESCRIPTION: * * This function obtains the attribute mask bits from the LdapRequest pointed * to by "request", creates the corresponding array of AttributeTypes for the * encoding of the SearchRequest message. * * PARAMETERS * "request" * The address of the LdapRequest whose attributes are to be encoded. Must * be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an LdapRequest Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_LdapRequest_EncodeAttrs( PKIX_PL_LdapRequest *request, void *plContext) { SECItem **attrArray = NULL; PKIX_UInt32 attrIndex = 0; LdapAttrMask attrBits; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs"); PKIX_NULLCHECK_ONE(request); /* construct "attrs" according to bits in request->attrBits */ attrBits = request->attrBits; attrArray = request->attrArray; if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) { attrArray[attrIndex] = &(request->attributes[attrIndex]); request->attributes[attrIndex].type = siAsciiString; request->attributes[attrIndex].data = (unsigned char *)caAttr; request->attributes[attrIndex].len = caAttrLen; attrIndex++; } if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) { attrArray[attrIndex] = &(request->attributes[attrIndex]); request->attributes[attrIndex].type = siAsciiString; request->attributes[attrIndex].data = (unsigned char *)uAttr; request->attributes[attrIndex].len = uAttrLen; attrIndex++; } if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) { attrArray[attrIndex] = &(request->attributes[attrIndex]); request->attributes[attrIndex].type = siAsciiString; request->attributes[attrIndex].data = (unsigned char *)ccpAttr; request->attributes[attrIndex].len = ccpAttrLen; attrIndex++; } if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) { attrArray[attrIndex] = &(request->attributes[attrIndex]); request->attributes[attrIndex].type = siAsciiString; request->attributes[attrIndex].data = (unsigned char *)crlAttr; request->attributes[attrIndex].len = crlAttrLen; attrIndex++; } if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) { attrArray[attrIndex] = &(request->attributes[attrIndex]); request->attributes[attrIndex].type = siAsciiString; request->attributes[attrIndex].data = (unsigned char *)arlAttr; request->attributes[attrIndex].len = arlAttrLen; attrIndex++; } attrArray[attrIndex] = (SECItem *)NULL; PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_Destroy * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_LdapRequest_Destroy( PKIX_PL_Object *object, void *plContext) { PKIX_PL_LdapRequest *ldapRq = NULL; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy"); PKIX_NULLCHECK_ONE(object); PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext), PKIX_OBJECTNOTLDAPREQUEST); ldapRq = (PKIX_PL_LdapRequest *)object; /* * All dynamic fields in an LDAPRequest are allocated * in an arena, and will be freed when the arena is destroyed. */ cleanup: PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_Hashcode * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_LdapRequest_Hashcode( PKIX_PL_Object *object, PKIX_UInt32 *pHashcode, void *plContext) { PKIX_UInt32 dataLen = 0; PKIX_UInt32 dindex = 0; PKIX_UInt32 sizeOfLength = 0; PKIX_UInt32 idLen = 0; const unsigned char *msgBuf = NULL; PKIX_PL_LdapRequest *ldapRq = NULL; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode"); PKIX_NULLCHECK_TWO(object, pHashcode); PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext), PKIX_OBJECTNOTLDAPREQUEST); ldapRq = (PKIX_PL_LdapRequest *)object; *pHashcode = 0; /* * Two requests that differ only in msgnum are a match! Therefore, * start hashcoding beyond the encoded messageID field. */ if (ldapRq->encoded) { msgBuf = (const unsigned char *)ldapRq->encoded->data; /* Is message length short form (one octet) or long form? */ if ((msgBuf[1] & 0x80) != 0) { sizeOfLength = msgBuf[1] & 0x7F; for (dindex = 0; dindex < sizeOfLength; dindex++) { dataLen = (dataLen << 8) + msgBuf[dindex + 2]; } } else { dataLen = msgBuf[1]; } /* How many bytes for the messageID? (Assume short form) */ idLen = msgBuf[dindex + 3] + 2; dindex += idLen; dataLen -= idLen; msgBuf = &msgBuf[dindex + 2]; PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext), PKIX_HASHFAILED); } cleanup: PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_Equals * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_LdapRequest_Equals( PKIX_PL_Object *firstObj, PKIX_PL_Object *secondObj, PKIX_Boolean *pResult, void *plContext) { PKIX_PL_LdapRequest *firstReq = NULL; PKIX_PL_LdapRequest *secondReq = NULL; PKIX_UInt32 secondType = 0; PKIX_UInt32 firstLen = 0; const unsigned char *firstData = NULL; const unsigned char *secondData = NULL; PKIX_UInt32 sizeOfLength = 0; PKIX_UInt32 dindex = 0; PKIX_UInt32 i = 0; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals"); PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult); /* test that firstObj is a LdapRequest */ PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext), PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST); /* * Since we know firstObj is a LdapRequest, if both references are * identical, they must be equal */ if (firstObj == secondObj){ *pResult = PKIX_TRUE; goto cleanup; } /* * If secondObj isn't a LdapRequest, we don't throw an error. * We simply return a Boolean result of FALSE */ *pResult = PKIX_FALSE; PKIX_CHECK(PKIX_PL_Object_GetType (secondObj, &secondType, plContext), PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); if (secondType != PKIX_LDAPREQUEST_TYPE) { goto cleanup; } firstReq = (PKIX_PL_LdapRequest *)firstObj; secondReq = (PKIX_PL_LdapRequest *)secondObj; /* If either lacks an encoded string, they cannot be compared */ if (!(firstReq->encoded) || !(secondReq->encoded)) { goto cleanup; } if (firstReq->encoded->len != secondReq->encoded->len) { goto cleanup; } firstData = (const unsigned char *)firstReq->encoded->data; secondData = (const unsigned char *)secondReq->encoded->data; /* * Two requests that differ only in msgnum are equal! Therefore, * start the byte comparison beyond the encoded messageID field. */ /* Is message length short form (one octet) or long form? */ if ((firstData[1] & 0x80) != 0) { sizeOfLength = firstData[1] & 0x7F; for (dindex = 0; dindex < sizeOfLength; dindex++) { firstLen = (firstLen << 8) + firstData[dindex + 2]; } } else { firstLen = firstData[1]; } /* How many bytes for the messageID? (Assume short form) */ i = firstData[dindex + 3] + 2; dindex += i; firstLen -= i; firstData = &firstData[dindex + 2]; /* * In theory, we have to calculate where the second message data * begins by checking its length encodings. But if these messages * are equal, we can re-use the calculation we already did. If they * are not equal, the byte comparisons will surely fail. */ secondData = &secondData[dindex + 2]; for (i = 0; i < firstLen; i++) { if (firstData[i] != secondData[i]) { goto cleanup; } } *pResult = PKIX_TRUE; cleanup: PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_RegisterSelf * DESCRIPTION: * Registers PKIX_LDAPREQUEST_TYPE and its related functions with * systemClasses[] * PARAMETERS: * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Not Thread Safe - for performance and complexity reasons * * Since this function is only called by PKIX_PL_Initialize, which should * only be called once, it is acceptable that this function is not * thread-safe. */ PKIX_Error * pkix_pl_LdapRequest_RegisterSelf(void *plContext) { extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; pkix_ClassTable_Entry entry; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf"); entry.description = "LdapRequest"; entry.objCounter = 0; entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest); entry.destructor = pkix_pl_LdapRequest_Destroy; entry.equalsFunction = pkix_pl_LdapRequest_Equals; entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode; entry.toStringFunction = NULL; entry.comparator = NULL; entry.duplicateFunction = pkix_duplicateImmutable; systemClasses[PKIX_LDAPREQUEST_TYPE] = entry; PKIX_RETURN(LDAPREQUEST); } /* --Public-Functions------------------------------------------------------- */ /* * FUNCTION: pkix_pl_LdapRequest_Create * DESCRIPTION: * * This function creates an LdapRequest using the PLArenaPool pointed to by * "arena", a message number whose value is "msgnum", a base object pointed to * by "issuerDN", a scope whose value is "scope", a derefAliases flag whose * value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit * whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a * filter whose value is "filter", and attribute bits whose value is * "attrBits"; storing the result at "pRequestMsg". * * See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of * message components, and see pkix_pl_ldapt.h for data types. * * PARAMETERS * "arena" * The address of the PLArenaPool to be used in the encoding. Must be * non-NULL. * "msgnum" * The UInt32 message number to be used for the messageID component of the * LDAP message exchange. * "issuerDN" * The address of the string to be used for the baseObject component of the * LDAP SearchRequest message. Must be non-NULL. * "scope" * The (enumerated) ScopeType to be used for the scope component of the * LDAP SearchRequest message * "derefAliases" * The (enumerated) DerefType to be used for the derefAliases component of * the LDAP SearchRequest message * "sizeLimit" * The UInt32 value to be used for the sizeLimit component of the LDAP * SearchRequest message * "timeLimit" * The UInt32 value to be used for the timeLimit component of the LDAP * SearchRequest message * "attrsOnly" * The Boolean value to be used for the attrsOnly component of the LDAP * SearchRequest message * "filter" * The filter to be used for the filter component of the LDAP * SearchRequest message * "attrBits" * The LdapAttrMask bits indicating the attributes to be included in the * attributes sequence of the LDAP SearchRequest message * "pRequestMsg" * The address at which the address of the LdapRequest is stored. Must * be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an LdapRequest Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ /* * SearchRequest ::= * [APPLICATION 3] SEQUENCE { * baseObject LDAPDN, * scope ENUMERATED { * baseObject (0), * singleLevel (1), * wholeSubtree (2) * }, * derefAliases ENUMERATED { * neverDerefAliases (0), * derefInSearching (1), * derefFindingBaseObj (2), * alwaysDerefAliases (3) * }, * sizeLimit INTEGER (0 .. MAXINT), * -- value of 0 implies no sizeLimit * timeLimit INTEGER (0 .. MAXINT), * -- value of 0 implies no timeLimit * attrsOnly BOOLEAN, * -- TRUE, if only attributes (without values) * -- to be returned * filter Filter, * attributes SEQUENCE OF AttributeType * } * * Filter ::= * CHOICE { * and [0] SET OF Filter, * or [1] SET OF Filter, * not [2] Filter, * equalityMatch [3] AttributeValueAssertion, * substrings [4] SubstringFilter, * greaterOrEqual [5] AttributeValueAssertion, * lessOrEqual [6] AttributeValueAssertion, * present [7] AttributeType, * approxMatch [8] AttributeValueAssertion * } * * SubstringFilter ::= * SEQUENCE { * type AttributeType, * SEQUENCE OF CHOICE { * initial [0] LDAPString, * any [1] LDAPString, * final [2] LDAPString, * } * } * * AttributeValueAssertion ::= * SEQUENCE { * attributeType AttributeType, * attributeValue AttributeValue, * } * * AttributeValue ::= OCTET STRING * * AttributeType ::= LDAPString * -- text name of the attribute, or dotted * -- OID representation * * LDAPDN ::= LDAPString * * LDAPString ::= OCTET STRING * */ PKIX_Error * pkix_pl_LdapRequest_Create( PLArenaPool *arena, PKIX_UInt32 msgnum, char *issuerDN, ScopeType scope, DerefType derefAliases, PKIX_UInt32 sizeLimit, PKIX_UInt32 timeLimit, char attrsOnly, LDAPFilter *filter, LdapAttrMask attrBits, PKIX_PL_LdapRequest **pRequestMsg, void *plContext) { LDAPMessage msg; LDAPSearch *search; PKIX_PL_LdapRequest *ldapRequest = NULL; char scopeTypeAsChar; char derefAliasesTypeAsChar; SECItem *attrArray[MAX_LDAPATTRS + 1]; PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create"); PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg); /* create a PKIX_PL_LdapRequest object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_LDAPREQUEST_TYPE, sizeof (PKIX_PL_LdapRequest), (PKIX_PL_Object **)&ldapRequest, plContext), PKIX_COULDNOTCREATEOBJECT); ldapRequest->arena = arena; ldapRequest->msgnum = msgnum; ldapRequest->issuerDN = issuerDN; ldapRequest->scope = scope; ldapRequest->derefAliases = derefAliases; ldapRequest->sizeLimit = sizeLimit; ldapRequest->timeLimit = timeLimit; ldapRequest->attrsOnly = attrsOnly; ldapRequest->filter = filter; ldapRequest->attrBits = attrBits; ldapRequest->attrArray = attrArray; PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs (ldapRequest, plContext), PKIX_LDAPREQUESTENCODEATTRSFAILED); PKIX_PL_NSSCALL (LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage))); msg.messageID.type = siUnsignedInteger; msg.messageID.data = (void*)&msgnum; msg.messageID.len = sizeof (msgnum); msg.protocolOp.selector = LDAP_SEARCH_TYPE; search = &(msg.protocolOp.op.searchMsg); search->baseObject.type = siAsciiString; search->baseObject.data = (void *)issuerDN; search->baseObject.len = PL_strlen(issuerDN); scopeTypeAsChar = (char)scope; search->scope.type = siUnsignedInteger; search->scope.data = (void *)&scopeTypeAsChar; search->scope.len = sizeof (scopeTypeAsChar); derefAliasesTypeAsChar = (char)derefAliases; search->derefAliases.type = siUnsignedInteger; search->derefAliases.data = (void *)&derefAliasesTypeAsChar; search->derefAliases.len = sizeof (derefAliasesTypeAsChar); search->sizeLimit.type = siUnsignedInteger; search->sizeLimit.data = (void *)&sizeLimit; search->sizeLimit.len = sizeof (PKIX_UInt32); search->timeLimit.type = siUnsignedInteger; search->timeLimit.data = (void *)&timeLimit; search->timeLimit.len = sizeof (PKIX_UInt32); search->attrsOnly.type = siBuffer; search->attrsOnly.data = (void *)&attrsOnly; search->attrsOnly.len = sizeof (attrsOnly); PKIX_PL_NSSCALL (LDAPREQUEST, PORT_Memcpy, (&search->filter, filter, sizeof (LDAPFilter))); search->attributes = attrArray; PKIX_PL_NSSCALLRV (LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem, (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate)); if (!(ldapRequest->encoded)) { PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST); } *pRequestMsg = ldapRequest; cleanup: if (PKIX_ERROR_RECEIVED) { PKIX_DECREF(ldapRequest); } PKIX_RETURN(LDAPREQUEST); } /* * FUNCTION: pkix_pl_LdapRequest_GetEncoded * DESCRIPTION: * * This function obtains the encoded message from the LdapRequest pointed to * by "request", storing the result at "pRequestBuf". * * PARAMETERS * "request" * The address of the LdapRequest whose encoded message is to be * retrieved. Must be non-NULL. * "pRequestBuf" * The address at which is stored the address of the encoded message. Must * be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an LdapRequest Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapRequest_GetEncoded( PKIX_PL_LdapRequest *request, SECItem **pRequestBuf, void *plContext) { PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded"); PKIX_NULLCHECK_TWO(request, pRequestBuf); *pRequestBuf = request->encoded; PKIX_RETURN(LDAPREQUEST); }