OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 /* | |
5 * pkix_pl_ldaprequest.c | |
6 * | |
7 */ | |
8 | |
9 #include "pkix_pl_ldaprequest.h" | |
10 | |
11 /* --Private-LdapRequest-Functions------------------------------------- */ | |
12 | |
13 /* Note: lengths do not include the NULL terminator */ | |
14 static const char caAttr[] = "caCertificate;binary"; | |
15 static unsigned int caAttrLen = sizeof(caAttr) - 1; | |
16 static const char uAttr[] = "userCertificate;binary"; | |
17 static unsigned int uAttrLen = sizeof(uAttr) - 1; | |
18 static const char ccpAttr[] = "crossCertificatePair;binary"; | |
19 static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1; | |
20 static const char crlAttr[] = "certificateRevocationList;binary"; | |
21 static unsigned int crlAttrLen = sizeof(crlAttr) - 1; | |
22 static const char arlAttr[] = "authorityRevocationList;binary"; | |
23 static unsigned int arlAttrLen = sizeof(arlAttr) - 1; | |
24 | |
25 /* | |
26 * XXX If this function were moved into pkix_pl_ldapcertstore.c then all of | |
27 * LdapRequest and LdapResponse could be considered part of the LDAP client. | |
28 * But the constants, above, would have to be copied as well, and they are | |
29 * also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be | |
30 * two copies. | |
31 */ | |
32 | |
33 /* | |
34 * FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit | |
35 * DESCRIPTION: | |
36 * | |
37 * This function creates an attribute mask bit corresponding to the SECItem | |
38 * pointed to by "attrType", storing the result at "pAttrBit". The comparison | |
39 * is case-insensitive. If "attrType" does not match any of the known types, | |
40 * zero is stored at "pAttrBit". | |
41 * | |
42 * PARAMETERS | |
43 * "attrType" | |
44 * The address of the SECItem whose string contents are to be compared to | |
45 * the various known attribute types. Must be non-NULL. | |
46 * "pAttrBit" | |
47 * The address where the result is stored. Must be non-NULL. | |
48 * "plContext" | |
49 * Platform-specific context pointer. | |
50 * THREAD SAFETY: | |
51 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
52 * RETURNS: | |
53 * Returns NULL if the function succeeds. | |
54 * Returns an LdapRequest Error if the function fails in a non-fatal way. | |
55 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
56 */ | |
57 PKIX_Error * | |
58 pkix_pl_LdapRequest_AttrTypeToBit( | |
59 SECItem *attrType, | |
60 LdapAttrMask *pAttrBit, | |
61 void *plContext) | |
62 { | |
63 LdapAttrMask attrBit = 0; | |
64 unsigned int attrLen = 0; | |
65 const char *s = NULL; | |
66 | |
67 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit"); | |
68 PKIX_NULLCHECK_TWO(attrType, pAttrBit); | |
69 | |
70 s = (const char *)attrType->data; | |
71 attrLen = attrType->len; | |
72 | |
73 /* | |
74 * Taking note of the fact that all of the comparand strings are | |
75 * different lengths, we do a slight optimization. If a string | |
76 * length matches but the string does not match, we skip comparing | |
77 * to the other strings. If new strings are added to the comparand | |
78 * list, and any are of equal length, be careful to change the | |
79 * grouping of tests accordingly. | |
80 */ | |
81 if (attrLen == caAttrLen) { | |
82 if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) { | |
83 attrBit = LDAPATTR_CACERT; | |
84 } | |
85 } else if (attrLen == uAttrLen) { | |
86 if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) { | |
87 attrBit = LDAPATTR_USERCERT; | |
88 } | |
89 } else if (attrLen == ccpAttrLen) { | |
90 if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) { | |
91 attrBit = LDAPATTR_CROSSPAIRCERT; | |
92 } | |
93 } else if (attrLen == crlAttrLen) { | |
94 if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) { | |
95 attrBit = LDAPATTR_CERTREVLIST; | |
96 } | |
97 } else if (attrLen == arlAttrLen) { | |
98 if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) { | |
99 attrBit = LDAPATTR_AUTHREVLIST; | |
100 } | |
101 } | |
102 | |
103 *pAttrBit = attrBit; | |
104 | |
105 PKIX_RETURN(LDAPREQUEST); | |
106 } | |
107 | |
108 /* | |
109 * FUNCTION: pkix_pl_LdapRequest_AttrStringToBit | |
110 * DESCRIPTION: | |
111 * | |
112 * This function creates an attribute mask bit corresponding to the null- | |
113 * terminated string pointed to by "attrString", storing the result at | |
114 * "pAttrBit". The comparison is case-insensitive. If "attrString" does not | |
115 * match any of the known types, zero is stored at "pAttrBit". | |
116 * | |
117 * PARAMETERS | |
118 * "attrString" | |
119 * The address of the null-terminated string whose contents are to be compa
red to | |
120 * the various known attribute types. Must be non-NULL. | |
121 * "pAttrBit" | |
122 * The address where the result is stored. Must be non-NULL. | |
123 * "plContext" | |
124 * Platform-specific context pointer. | |
125 * THREAD SAFETY: | |
126 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
127 * RETURNS: | |
128 * Returns NULL if the function succeeds. | |
129 * Returns an LdapRequest Error if the function fails in a non-fatal way. | |
130 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
131 */ | |
132 PKIX_Error * | |
133 pkix_pl_LdapRequest_AttrStringToBit( | |
134 char *attrString, | |
135 LdapAttrMask *pAttrBit, | |
136 void *plContext) | |
137 { | |
138 LdapAttrMask attrBit = 0; | |
139 unsigned int attrLen = 0; | |
140 | |
141 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit"); | |
142 PKIX_NULLCHECK_TWO(attrString, pAttrBit); | |
143 | |
144 attrLen = PL_strlen(attrString); | |
145 | |
146 /* | |
147 * Taking note of the fact that all of the comparand strings are | |
148 * different lengths, we do a slight optimization. If a string | |
149 * length matches but the string does not match, we skip comparing | |
150 * to the other strings. If new strings are added to the comparand | |
151 * list, and any are of equal length, be careful to change the | |
152 * grouping of tests accordingly. | |
153 */ | |
154 if (attrLen == caAttrLen) { | |
155 if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) { | |
156 attrBit = LDAPATTR_CACERT; | |
157 } | |
158 } else if (attrLen == uAttrLen) { | |
159 if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) { | |
160 attrBit = LDAPATTR_USERCERT; | |
161 } | |
162 } else if (attrLen == ccpAttrLen) { | |
163 if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) { | |
164 attrBit = LDAPATTR_CROSSPAIRCERT; | |
165 } | |
166 } else if (attrLen == crlAttrLen) { | |
167 if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) { | |
168 attrBit = LDAPATTR_CERTREVLIST; | |
169 } | |
170 } else if (attrLen == arlAttrLen) { | |
171 if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) { | |
172 attrBit = LDAPATTR_AUTHREVLIST; | |
173 } | |
174 } | |
175 | |
176 *pAttrBit = attrBit; | |
177 | |
178 PKIX_RETURN(LDAPREQUEST); | |
179 } | |
180 | |
181 /* | |
182 * FUNCTION: pkix_pl_LdapRequest_EncodeAttrs | |
183 * DESCRIPTION: | |
184 * | |
185 * This function obtains the attribute mask bits from the LdapRequest pointed | |
186 * to by "request", creates the corresponding array of AttributeTypes for the | |
187 * encoding of the SearchRequest message. | |
188 * | |
189 * PARAMETERS | |
190 * "request" | |
191 * The address of the LdapRequest whose attributes are to be encoded. Must | |
192 * be non-NULL. | |
193 * "plContext" | |
194 * Platform-specific context pointer. | |
195 * THREAD SAFETY: | |
196 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
197 * RETURNS: | |
198 * Returns NULL if the function succeeds. | |
199 * Returns an LdapRequest Error if the function fails in a non-fatal way. | |
200 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
201 */ | |
202 static PKIX_Error * | |
203 pkix_pl_LdapRequest_EncodeAttrs( | |
204 PKIX_PL_LdapRequest *request, | |
205 void *plContext) | |
206 { | |
207 SECItem **attrArray = NULL; | |
208 PKIX_UInt32 attrIndex = 0; | |
209 LdapAttrMask attrBits; | |
210 | |
211 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs"); | |
212 PKIX_NULLCHECK_ONE(request); | |
213 | |
214 /* construct "attrs" according to bits in request->attrBits */ | |
215 attrBits = request->attrBits; | |
216 attrArray = request->attrArray; | |
217 if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) { | |
218 attrArray[attrIndex] = &(request->attributes[attrIndex]); | |
219 request->attributes[attrIndex].type = siAsciiString; | |
220 request->attributes[attrIndex].data = (unsigned char *)caAttr; | |
221 request->attributes[attrIndex].len = caAttrLen; | |
222 attrIndex++; | |
223 } | |
224 if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) { | |
225 attrArray[attrIndex] = &(request->attributes[attrIndex]); | |
226 request->attributes[attrIndex].type = siAsciiString; | |
227 request->attributes[attrIndex].data = (unsigned char *)uAttr; | |
228 request->attributes[attrIndex].len = uAttrLen; | |
229 attrIndex++; | |
230 } | |
231 if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) { | |
232 attrArray[attrIndex] = &(request->attributes[attrIndex]); | |
233 request->attributes[attrIndex].type = siAsciiString; | |
234 request->attributes[attrIndex].data = (unsigned char *)ccpAttr; | |
235 request->attributes[attrIndex].len = ccpAttrLen; | |
236 attrIndex++; | |
237 } | |
238 if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) { | |
239 attrArray[attrIndex] = &(request->attributes[attrIndex]); | |
240 request->attributes[attrIndex].type = siAsciiString; | |
241 request->attributes[attrIndex].data = (unsigned char *)crlAttr; | |
242 request->attributes[attrIndex].len = crlAttrLen; | |
243 attrIndex++; | |
244 } | |
245 if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) { | |
246 attrArray[attrIndex] = &(request->attributes[attrIndex]); | |
247 request->attributes[attrIndex].type = siAsciiString; | |
248 request->attributes[attrIndex].data = (unsigned char *)arlAttr; | |
249 request->attributes[attrIndex].len = arlAttrLen; | |
250 attrIndex++; | |
251 } | |
252 attrArray[attrIndex] = (SECItem *)NULL; | |
253 | |
254 PKIX_RETURN(LDAPREQUEST); | |
255 } | |
256 | |
257 /* | |
258 * FUNCTION: pkix_pl_LdapRequest_Destroy | |
259 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
260 */ | |
261 static PKIX_Error * | |
262 pkix_pl_LdapRequest_Destroy( | |
263 PKIX_PL_Object *object, | |
264 void *plContext) | |
265 { | |
266 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy"); | |
267 PKIX_NULLCHECK_ONE(object); | |
268 | |
269 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext), | |
270 PKIX_OBJECTNOTLDAPREQUEST); | |
271 | |
272 /* | |
273 * All dynamic fields in an LDAPRequest are allocated | |
274 * in an arena, and will be freed when the arena is destroyed. | |
275 */ | |
276 | |
277 cleanup: | |
278 | |
279 PKIX_RETURN(LDAPREQUEST); | |
280 } | |
281 | |
282 /* | |
283 * FUNCTION: pkix_pl_LdapRequest_Hashcode | |
284 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
285 */ | |
286 static PKIX_Error * | |
287 pkix_pl_LdapRequest_Hashcode( | |
288 PKIX_PL_Object *object, | |
289 PKIX_UInt32 *pHashcode, | |
290 void *plContext) | |
291 { | |
292 PKIX_UInt32 dataLen = 0; | |
293 PKIX_UInt32 dindex = 0; | |
294 PKIX_UInt32 sizeOfLength = 0; | |
295 PKIX_UInt32 idLen = 0; | |
296 const unsigned char *msgBuf = NULL; | |
297 PKIX_PL_LdapRequest *ldapRq = NULL; | |
298 | |
299 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode"); | |
300 PKIX_NULLCHECK_TWO(object, pHashcode); | |
301 | |
302 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext), | |
303 PKIX_OBJECTNOTLDAPREQUEST); | |
304 | |
305 ldapRq = (PKIX_PL_LdapRequest *)object; | |
306 | |
307 *pHashcode = 0; | |
308 | |
309 /* | |
310 * Two requests that differ only in msgnum are a match! Therefore, | |
311 * start hashcoding beyond the encoded messageID field. | |
312 */ | |
313 if (ldapRq->encoded) { | |
314 msgBuf = (const unsigned char *)ldapRq->encoded->data; | |
315 /* Is message length short form (one octet) or long form? */ | |
316 if ((msgBuf[1] & 0x80) != 0) { | |
317 sizeOfLength = msgBuf[1] & 0x7F; | |
318 for (dindex = 0; dindex < sizeOfLength; dindex++) { | |
319 dataLen = (dataLen << 8) + msgBuf[dindex + 2]; | |
320 } | |
321 } else { | |
322 dataLen = msgBuf[1]; | |
323 } | |
324 | |
325 /* How many bytes for the messageID? (Assume short form) */ | |
326 idLen = msgBuf[dindex + 3] + 2; | |
327 dindex += idLen; | |
328 dataLen -= idLen; | |
329 msgBuf = &msgBuf[dindex + 2]; | |
330 | |
331 PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext), | |
332 PKIX_HASHFAILED); | |
333 } | |
334 | |
335 cleanup: | |
336 | |
337 PKIX_RETURN(LDAPREQUEST); | |
338 | |
339 } | |
340 | |
341 /* | |
342 * FUNCTION: pkix_pl_LdapRequest_Equals | |
343 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
344 */ | |
345 static PKIX_Error * | |
346 pkix_pl_LdapRequest_Equals( | |
347 PKIX_PL_Object *firstObj, | |
348 PKIX_PL_Object *secondObj, | |
349 PKIX_Boolean *pResult, | |
350 void *plContext) | |
351 { | |
352 PKIX_PL_LdapRequest *firstReq = NULL; | |
353 PKIX_PL_LdapRequest *secondReq = NULL; | |
354 PKIX_UInt32 secondType = 0; | |
355 PKIX_UInt32 firstLen = 0; | |
356 const unsigned char *firstData = NULL; | |
357 const unsigned char *secondData = NULL; | |
358 PKIX_UInt32 sizeOfLength = 0; | |
359 PKIX_UInt32 dindex = 0; | |
360 PKIX_UInt32 i = 0; | |
361 | |
362 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals"); | |
363 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult); | |
364 | |
365 /* test that firstObj is a LdapRequest */ | |
366 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext), | |
367 PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST); | |
368 | |
369 /* | |
370 * Since we know firstObj is a LdapRequest, if both references are | |
371 * identical, they must be equal | |
372 */ | |
373 if (firstObj == secondObj){ | |
374 *pResult = PKIX_TRUE; | |
375 goto cleanup; | |
376 } | |
377 | |
378 /* | |
379 * If secondObj isn't a LdapRequest, we don't throw an error. | |
380 * We simply return a Boolean result of FALSE | |
381 */ | |
382 *pResult = PKIX_FALSE; | |
383 PKIX_CHECK(PKIX_PL_Object_GetType | |
384 (secondObj, &secondType, plContext), | |
385 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
386 if (secondType != PKIX_LDAPREQUEST_TYPE) { | |
387 goto cleanup; | |
388 } | |
389 | |
390 firstReq = (PKIX_PL_LdapRequest *)firstObj; | |
391 secondReq = (PKIX_PL_LdapRequest *)secondObj; | |
392 | |
393 /* If either lacks an encoded string, they cannot be compared */ | |
394 if (!(firstReq->encoded) || !(secondReq->encoded)) { | |
395 goto cleanup; | |
396 } | |
397 | |
398 if (firstReq->encoded->len != secondReq->encoded->len) { | |
399 goto cleanup; | |
400 } | |
401 | |
402 firstData = (const unsigned char *)firstReq->encoded->data; | |
403 secondData = (const unsigned char *)secondReq->encoded->data; | |
404 | |
405 /* | |
406 * Two requests that differ only in msgnum are equal! Therefore, | |
407 * start the byte comparison beyond the encoded messageID field. | |
408 */ | |
409 | |
410 /* Is message length short form (one octet) or long form? */ | |
411 if ((firstData[1] & 0x80) != 0) { | |
412 sizeOfLength = firstData[1] & 0x7F; | |
413 for (dindex = 0; dindex < sizeOfLength; dindex++) { | |
414 firstLen = (firstLen << 8) + firstData[dindex + 2]; | |
415 } | |
416 } else { | |
417 firstLen = firstData[1]; | |
418 } | |
419 | |
420 /* How many bytes for the messageID? (Assume short form) */ | |
421 i = firstData[dindex + 3] + 2; | |
422 dindex += i; | |
423 firstLen -= i; | |
424 firstData = &firstData[dindex + 2]; | |
425 | |
426 /* | |
427 * In theory, we have to calculate where the second message data | |
428 * begins by checking its length encodings. But if these messages | |
429 * are equal, we can re-use the calculation we already did. If they | |
430 * are not equal, the byte comparisons will surely fail. | |
431 */ | |
432 | |
433 secondData = &secondData[dindex + 2]; | |
434 | |
435 for (i = 0; i < firstLen; i++) { | |
436 if (firstData[i] != secondData[i]) { | |
437 goto cleanup; | |
438 } | |
439 } | |
440 | |
441 *pResult = PKIX_TRUE; | |
442 | |
443 cleanup: | |
444 | |
445 PKIX_RETURN(LDAPREQUEST); | |
446 } | |
447 | |
448 /* | |
449 * FUNCTION: pkix_pl_LdapRequest_RegisterSelf | |
450 * DESCRIPTION: | |
451 * Registers PKIX_LDAPREQUEST_TYPE and its related functions with | |
452 * systemClasses[] | |
453 * PARAMETERS: | |
454 * "plContext" | |
455 * Platform-specific context pointer. | |
456 * THREAD SAFETY: | |
457 * Not Thread Safe - for performance and complexity reasons | |
458 * | |
459 * Since this function is only called by PKIX_PL_Initialize, which should | |
460 * only be called once, it is acceptable that this function is not | |
461 * thread-safe. | |
462 */ | |
463 PKIX_Error * | |
464 pkix_pl_LdapRequest_RegisterSelf(void *plContext) | |
465 { | |
466 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
467 pkix_ClassTable_Entry entry; | |
468 | |
469 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf"); | |
470 | |
471 entry.description = "LdapRequest"; | |
472 entry.objCounter = 0; | |
473 entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest); | |
474 entry.destructor = pkix_pl_LdapRequest_Destroy; | |
475 entry.equalsFunction = pkix_pl_LdapRequest_Equals; | |
476 entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode; | |
477 entry.toStringFunction = NULL; | |
478 entry.comparator = NULL; | |
479 entry.duplicateFunction = pkix_duplicateImmutable; | |
480 | |
481 systemClasses[PKIX_LDAPREQUEST_TYPE] = entry; | |
482 | |
483 PKIX_RETURN(LDAPREQUEST); | |
484 } | |
485 | |
486 /* --Public-Functions------------------------------------------------------- */ | |
487 | |
488 /* | |
489 * FUNCTION: pkix_pl_LdapRequest_Create | |
490 * DESCRIPTION: | |
491 * | |
492 * This function creates an LdapRequest using the PLArenaPool pointed to by | |
493 * "arena", a message number whose value is "msgnum", a base object pointed to | |
494 * by "issuerDN", a scope whose value is "scope", a derefAliases flag whose | |
495 * value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit | |
496 * whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a | |
497 * filter whose value is "filter", and attribute bits whose value is | |
498 * "attrBits"; storing the result at "pRequestMsg". | |
499 * | |
500 * See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of | |
501 * message components, and see pkix_pl_ldapt.h for data types. | |
502 * | |
503 * PARAMETERS | |
504 * "arena" | |
505 * The address of the PLArenaPool to be used in the encoding. Must be | |
506 * non-NULL. | |
507 * "msgnum" | |
508 * The UInt32 message number to be used for the messageID component of the | |
509 * LDAP message exchange. | |
510 * "issuerDN" | |
511 * The address of the string to be used for the baseObject component of the | |
512 * LDAP SearchRequest message. Must be non-NULL. | |
513 * "scope" | |
514 * The (enumerated) ScopeType to be used for the scope component of the | |
515 * LDAP SearchRequest message | |
516 * "derefAliases" | |
517 * The (enumerated) DerefType to be used for the derefAliases component of | |
518 * the LDAP SearchRequest message | |
519 * "sizeLimit" | |
520 * The UInt32 value to be used for the sizeLimit component of the LDAP | |
521 * SearchRequest message | |
522 * "timeLimit" | |
523 * The UInt32 value to be used for the timeLimit component of the LDAP | |
524 * SearchRequest message | |
525 * "attrsOnly" | |
526 * The Boolean value to be used for the attrsOnly component of the LDAP | |
527 * SearchRequest message | |
528 * "filter" | |
529 * The filter to be used for the filter component of the LDAP | |
530 * SearchRequest message | |
531 * "attrBits" | |
532 * The LdapAttrMask bits indicating the attributes to be included in the | |
533 * attributes sequence of the LDAP SearchRequest message | |
534 * "pRequestMsg" | |
535 * The address at which the address of the LdapRequest is stored. Must | |
536 * be non-NULL. | |
537 * "plContext" | |
538 * Platform-specific context pointer. | |
539 * THREAD SAFETY: | |
540 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
541 * RETURNS: | |
542 * Returns NULL if the function succeeds. | |
543 * Returns an LdapRequest Error if the function fails in a non-fatal way. | |
544 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
545 */ | |
546 /* | |
547 * SearchRequest ::= | |
548 * [APPLICATION 3] SEQUENCE { | |
549 * baseObject LDAPDN, | |
550 * scope ENUMERATED { | |
551 * baseObject (0), | |
552 * singleLevel (1), | |
553 * wholeSubtree (2) | |
554 * }, | |
555 * derefAliases ENUMERATED { | |
556 * neverDerefAliases (0), | |
557 * derefInSearching (1), | |
558 * derefFindingBaseObj (2), | |
559 * alwaysDerefAliases (3) | |
560 * }, | |
561 * sizeLimit INTEGER (0 .. MAXINT), | |
562 * -- value of 0 implies no sizeLimit | |
563 * timeLimit INTEGER (0 .. MAXINT), | |
564 * -- value of 0 implies no timeLimit | |
565 * attrsOnly BOOLEAN, | |
566 * -- TRUE, if only attributes (without values) | |
567 * -- to be returned | |
568 * filter Filter, | |
569 * attributes SEQUENCE OF AttributeType | |
570 * } | |
571 * | |
572 * Filter ::= | |
573 * CHOICE { | |
574 * and [0] SET OF Filter, | |
575 * or [1] SET OF Filter, | |
576 * not [2] Filter, | |
577 * equalityMatch [3] AttributeValueAssertion, | |
578 * substrings [4] SubstringFilter, | |
579 * greaterOrEqual [5] AttributeValueAssertion, | |
580 * lessOrEqual [6] AttributeValueAssertion, | |
581 * present [7] AttributeType, | |
582 * approxMatch [8] AttributeValueAssertion | |
583 * } | |
584 * | |
585 * SubstringFilter ::= | |
586 * SEQUENCE { | |
587 * type AttributeType, | |
588 * SEQUENCE OF CHOICE { | |
589 * initial [0] LDAPString, | |
590 * any [1] LDAPString, | |
591 * final [2] LDAPString, | |
592 * } | |
593 * } | |
594 * | |
595 * AttributeValueAssertion ::= | |
596 * SEQUENCE { | |
597 * attributeType AttributeType, | |
598 * attributeValue AttributeValue, | |
599 * } | |
600 * | |
601 * AttributeValue ::= OCTET STRING | |
602 * | |
603 * AttributeType ::= LDAPString | |
604 * -- text name of the attribute, or dotted | |
605 * -- OID representation | |
606 * | |
607 * LDAPDN ::= LDAPString | |
608 * | |
609 * LDAPString ::= OCTET STRING | |
610 * | |
611 */ | |
612 PKIX_Error * | |
613 pkix_pl_LdapRequest_Create( | |
614 PLArenaPool *arena, | |
615 PKIX_UInt32 msgnum, | |
616 char *issuerDN, | |
617 ScopeType scope, | |
618 DerefType derefAliases, | |
619 PKIX_UInt32 sizeLimit, | |
620 PKIX_UInt32 timeLimit, | |
621 char attrsOnly, | |
622 LDAPFilter *filter, | |
623 LdapAttrMask attrBits, | |
624 PKIX_PL_LdapRequest **pRequestMsg, | |
625 void *plContext) | |
626 { | |
627 LDAPMessage msg; | |
628 LDAPSearch *search; | |
629 PKIX_PL_LdapRequest *ldapRequest = NULL; | |
630 char scopeTypeAsChar; | |
631 char derefAliasesTypeAsChar; | |
632 SECItem *attrArray[MAX_LDAPATTRS + 1]; | |
633 | |
634 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create"); | |
635 PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg); | |
636 | |
637 /* create a PKIX_PL_LdapRequest object */ | |
638 PKIX_CHECK(PKIX_PL_Object_Alloc | |
639 (PKIX_LDAPREQUEST_TYPE, | |
640 sizeof (PKIX_PL_LdapRequest), | |
641 (PKIX_PL_Object **)&ldapRequest, | |
642 plContext), | |
643 PKIX_COULDNOTCREATEOBJECT); | |
644 | |
645 ldapRequest->arena = arena; | |
646 ldapRequest->msgnum = msgnum; | |
647 ldapRequest->issuerDN = issuerDN; | |
648 ldapRequest->scope = scope; | |
649 ldapRequest->derefAliases = derefAliases; | |
650 ldapRequest->sizeLimit = sizeLimit; | |
651 ldapRequest->timeLimit = timeLimit; | |
652 ldapRequest->attrsOnly = attrsOnly; | |
653 ldapRequest->filter = filter; | |
654 ldapRequest->attrBits = attrBits; | |
655 | |
656 ldapRequest->attrArray = attrArray; | |
657 | |
658 PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs | |
659 (ldapRequest, plContext), | |
660 PKIX_LDAPREQUESTENCODEATTRSFAILED); | |
661 | |
662 PKIX_PL_NSSCALL | |
663 (LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage))); | |
664 | |
665 msg.messageID.type = siUnsignedInteger; | |
666 msg.messageID.data = (void*)&msgnum; | |
667 msg.messageID.len = sizeof (msgnum); | |
668 | |
669 msg.protocolOp.selector = LDAP_SEARCH_TYPE; | |
670 | |
671 search = &(msg.protocolOp.op.searchMsg); | |
672 | |
673 search->baseObject.type = siAsciiString; | |
674 search->baseObject.data = (void *)issuerDN; | |
675 search->baseObject.len = PL_strlen(issuerDN); | |
676 scopeTypeAsChar = (char)scope; | |
677 search->scope.type = siUnsignedInteger; | |
678 search->scope.data = (void *)&scopeTypeAsChar; | |
679 search->scope.len = sizeof (scopeTypeAsChar); | |
680 derefAliasesTypeAsChar = (char)derefAliases; | |
681 search->derefAliases.type = siUnsignedInteger; | |
682 search->derefAliases.data = | |
683 (void *)&derefAliasesTypeAsChar; | |
684 search->derefAliases.len = | |
685 sizeof (derefAliasesTypeAsChar); | |
686 search->sizeLimit.type = siUnsignedInteger; | |
687 search->sizeLimit.data = (void *)&sizeLimit; | |
688 search->sizeLimit.len = sizeof (PKIX_UInt32); | |
689 search->timeLimit.type = siUnsignedInteger; | |
690 search->timeLimit.data = (void *)&timeLimit; | |
691 search->timeLimit.len = sizeof (PKIX_UInt32); | |
692 search->attrsOnly.type = siBuffer; | |
693 search->attrsOnly.data = (void *)&attrsOnly; | |
694 search->attrsOnly.len = sizeof (attrsOnly); | |
695 | |
696 PKIX_PL_NSSCALL | |
697 (LDAPREQUEST, | |
698 PORT_Memcpy, | |
699 (&search->filter, filter, sizeof (LDAPFilter))); | |
700 | |
701 search->attributes = attrArray; | |
702 | |
703 PKIX_PL_NSSCALLRV | |
704 (LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem, | |
705 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate)); | |
706 | |
707 if (!(ldapRequest->encoded)) { | |
708 PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST); | |
709 } | |
710 | |
711 *pRequestMsg = ldapRequest; | |
712 | |
713 cleanup: | |
714 | |
715 if (PKIX_ERROR_RECEIVED) { | |
716 PKIX_DECREF(ldapRequest); | |
717 } | |
718 | |
719 PKIX_RETURN(LDAPREQUEST); | |
720 } | |
721 | |
722 /* | |
723 * FUNCTION: pkix_pl_LdapRequest_GetEncoded | |
724 * DESCRIPTION: | |
725 * | |
726 * This function obtains the encoded message from the LdapRequest pointed to | |
727 * by "request", storing the result at "pRequestBuf". | |
728 * | |
729 * PARAMETERS | |
730 * "request" | |
731 * The address of the LdapRequest whose encoded message is to be | |
732 * retrieved. Must be non-NULL. | |
733 * "pRequestBuf" | |
734 * The address at which is stored the address of the encoded message. Must | |
735 * be non-NULL. | |
736 * "plContext" | |
737 * Platform-specific context pointer. | |
738 * THREAD SAFETY: | |
739 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
740 * RETURNS: | |
741 * Returns NULL if the function succeeds. | |
742 * Returns an LdapRequest Error if the function fails in a non-fatal way. | |
743 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
744 */ | |
745 PKIX_Error * | |
746 pkix_pl_LdapRequest_GetEncoded( | |
747 PKIX_PL_LdapRequest *request, | |
748 SECItem **pRequestBuf, | |
749 void *plContext) | |
750 { | |
751 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded"); | |
752 PKIX_NULLCHECK_TWO(request, pRequestBuf); | |
753 | |
754 *pRequestBuf = request->encoded; | |
755 | |
756 PKIX_RETURN(LDAPREQUEST); | |
757 } | |
OLD | NEW |