2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2006 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* Portions Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
17 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
18 * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
19 * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
20 * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
21 * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
22 * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
23 * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
24 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
26 * Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
27 * can be found in the file "build/LICENSE-2.0.1" in this distribution
28 * of OpenLDAP Software.
30 /* Portions Copyright (C) The Internet Society (1997)
31 * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
37 #include <ac/stdlib.h>
38 #include <ac/string.h>
43 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
44 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
45 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
49 ldap_create_vlv_control
51 Create and encode the Virtual List View control.
53 ld (IN) An LDAP session handle.
55 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
56 are used to construct the value of the control
59 value (OUT) A struct berval that contains the value to be assigned to the ldctl_value member
60 of an LDAPControl structure that contains the
61 VirtualListViewRequest control.
62 The bv_val member of the berval structure
63 SHOULD be freed when it is no longer in use by
64 calling ldap_memfree().
69 VirtualListViewRequest ::= SEQUENCE {
70 beforeCount INTEGER (0 .. maxInt),
71 afterCount INTEGER (0 .. maxInt),
73 byoffset [0] SEQUENCE, {
74 offset INTEGER (0 .. maxInt),
75 contentCount INTEGER (0 .. maxInt) }
76 [1] greaterThanOrEqual assertionValue }
77 contextID OCTET STRING OPTIONAL }
80 Note: The first time the VLV control is created, the ldvlv_context
81 field of the LDAPVLVInfo structure should be set to NULL.
82 The context obtained from calling ldap_parse_vlv_control()
83 should be used as the context in the next ldap_create_vlv_control
89 ldap_create_vlv_control_value(
91 LDAPVLVInfo *vlvinfop,
92 struct berval *value )
97 if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
99 ld->ld_errno = LDAP_PARAM_ERROR;
100 return LDAP_PARAM_ERROR;
103 assert( LDAP_VALID( ld ) );
105 value->bv_val = NULL;
108 ber = ldap_alloc_ber_with_options( ld );
110 ld->ld_errno = LDAP_NO_MEMORY;
114 tag = ber_printf( ber, "{ii" /*}*/,
115 vlvinfop->ldvlv_before_count,
116 vlvinfop->ldvlv_after_count );
117 if ( tag == LBER_ERROR ) {
121 if ( vlvinfop->ldvlv_attrvalue == NULL ) {
122 tag = ber_printf( ber, "t{iiN}",
123 LDAP_VLVBYINDEX_IDENTIFIER,
124 vlvinfop->ldvlv_offset,
125 vlvinfop->ldvlv_count );
126 if ( tag == LBER_ERROR ) {
131 tag = ber_printf( ber, "tO",
132 LDAP_VLVBYVALUE_IDENTIFIER,
133 vlvinfop->ldvlv_attrvalue );
134 if ( tag == LBER_ERROR ) {
139 if ( vlvinfop->ldvlv_context ) {
140 tag = ber_printf( ber, "tO",
141 LDAP_VLVCONTEXT_IDENTIFIER,
142 vlvinfop->ldvlv_context );
143 if ( tag == LBER_ERROR ) {
148 tag = ber_printf( ber, /*{*/ "N}" );
149 if ( tag == LBER_ERROR ) {
153 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
154 ld->ld_errno = LDAP_NO_MEMORY;
159 ld->ld_errno = LDAP_ENCODING_ERROR;
170 ldap_create_vlv_control
172 Create and encode the Virtual List View control.
174 ld (IN) An LDAP session handle.
176 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
177 are used to construct the value of the control
180 ctrlp (OUT) A result parameter that will be assigned the address
181 of an LDAPControl structure that contains the
182 VirtualListViewRequest control created by this function.
183 The memory occupied by the LDAPControl structure
184 SHOULD be freed when it is no longer in use by
185 calling ldap_control_free().
190 VirtualListViewRequest ::= SEQUENCE {
191 beforeCount INTEGER (0 .. maxInt),
192 afterCount INTEGER (0 .. maxInt),
194 byoffset [0] SEQUENCE, {
195 offset INTEGER (0 .. maxInt),
196 contentCount INTEGER (0 .. maxInt) }
197 [1] greaterThanOrEqual assertionValue }
198 contextID OCTET STRING OPTIONAL }
201 Note: The first time the VLV control is created, the ldvlv_context
202 field of the LDAPVLVInfo structure should be set to NULL.
203 The context obtained from calling ldap_parse_vlv_control()
204 should be used as the context in the next ldap_create_vlv_control
210 ldap_create_vlv_control(
212 LDAPVLVInfo *vlvinfop,
213 LDAPControl **ctrlp )
218 if ( ctrlp == NULL ) {
219 ld->ld_errno = LDAP_PARAM_ERROR;
223 ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
224 if ( ld->ld_errno == LDAP_SUCCESS ) {
225 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
226 ld->ld_errno = LDAP_NO_MEMORY;
227 return LDAP_NO_MEMORY;
230 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
232 if ( ld->ld_errno == LDAP_SUCCESS ) {
233 (*ctrlp)->ldctl_value = value;
235 LDAP_FREE( value.bv_val );
245 ldap_parse_vlvresponse_control
247 Decode the Virtual List View control return information.
249 ld (IN) An LDAP session handle.
251 ctrl (IN) The address of the LDAPControl structure.
253 target_posp (OUT) This result parameter is filled in with the list
254 index of the target entry. If this parameter is
255 NULL, the target position is not returned.
257 list_countp (OUT) This result parameter is filled in with the server's
258 estimate of the size of the list. If this parameter
259 is NULL, the size is not returned.
261 contextp (OUT) This result parameter is filled in with the address
262 of a struct berval that contains the server-
263 generated context identifier if one was returned by
264 the server. If the server did not return a context
265 identifier, this parameter will be set to NULL, even
267 The returned context SHOULD be used in the next call
268 to create a VLV sort control. The struct berval
269 returned SHOULD be disposed of by calling ber_bvfree()
270 when it is no longer needed. If NULL is passed for
271 contextp, the context identifier is not returned.
273 errcodep (OUT) This result parameter is filled in with the VLV
274 result code. If this parameter is NULL, the result
275 code is not returned.
280 VirtualListViewResponse ::= SEQUENCE {
281 targetPosition INTEGER (0 .. maxInt),
282 contentCount INTEGER (0 .. maxInt),
283 virtualListViewResult ENUMERATED {
286 unwillingToPerform (53),
287 insufficientAccessRights (50),
289 timeLimitExceeded (3),
290 adminLimitExceeded (11),
291 sortControlMissing (60),
292 offsetRangeError (61),
294 contextID OCTET STRING OPTIONAL }
299 ldap_parse_vlvresponse_control(
302 ber_int_t *target_posp,
303 ber_int_t *list_countp,
304 struct berval **contextp,
305 ber_int_t *errcodep )
308 ber_int_t pos, count, err;
309 ber_tag_t tag, berTag;
312 assert( ld != NULL );
313 assert( LDAP_VALID( ld ) );
316 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
320 ld->ld_errno = LDAP_PARAM_ERROR;
321 return(ld->ld_errno);
324 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
325 /* Not VLV Response control */
326 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
327 return(ld->ld_errno);
330 /* Create a BerElement from the berval returned in the control. */
331 ber = ber_init(&ctrl->ldctl_value);
334 ld->ld_errno = LDAP_NO_MEMORY;
335 return(ld->ld_errno);
338 /* Extract the data returned in the control. */
339 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
341 if( tag == LBER_ERROR) {
343 ld->ld_errno = LDAP_DECODING_ERROR;
344 return(ld->ld_errno);
348 /* Since the context is the last item encoded, if caller doesn't want
349 it returned, don't decode it. */
351 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
352 tag = ber_scanf(ber, "tO", &berTag, contextp);
354 if( tag == LBER_ERROR) {
356 ld->ld_errno = LDAP_DECODING_ERROR;
357 return(ld->ld_errno);
364 /* Return data to the caller for items that were requested. */
365 if (target_posp) *target_posp = pos;
366 if (list_countp) *list_countp = count;
367 if (errcodep) *errcodep = err;
369 ld->ld_errno = LDAP_SUCCESS;
370 return(ld->ld_errno);