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 ) {
98 ld->ld_errno = LDAP_PARAM_ERROR;
102 assert( LDAP_VALID( ld ) );
104 value->bv_val = NULL;
107 ber = ldap_alloc_ber_with_options( ld );
109 ld->ld_errno = LDAP_NO_MEMORY;
113 tag = ber_printf( ber, "{ii" /*}*/,
114 vlvinfop->ldvlv_before_count,
115 vlvinfop->ldvlv_after_count );
116 if ( tag == LBER_ERROR ) {
120 if ( vlvinfop->ldvlv_attrvalue == NULL ) {
121 tag = ber_printf( ber, "t{iiN}",
122 LDAP_VLVBYINDEX_IDENTIFIER,
123 vlvinfop->ldvlv_offset,
124 vlvinfop->ldvlv_count );
125 if ( tag == LBER_ERROR ) {
130 tag = ber_printf( ber, "tO",
131 LDAP_VLVBYVALUE_IDENTIFIER,
132 vlvinfop->ldvlv_attrvalue );
133 if ( tag == LBER_ERROR ) {
138 if ( vlvinfop->ldvlv_context ) {
139 tag = ber_printf( ber, "tO",
140 LDAP_VLVCONTEXT_IDENTIFIER,
141 vlvinfop->ldvlv_context );
142 if ( tag == LBER_ERROR ) {
147 tag = ber_printf( ber, /*{*/ "N}" );
148 if ( tag == LBER_ERROR ) {
152 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
153 ld->ld_errno = LDAP_NO_MEMORY;
158 ld->ld_errno = LDAP_ENCODING_ERROR;
169 ldap_create_vlv_control
171 Create and encode the Virtual List View control.
173 ld (IN) An LDAP session handle.
175 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
176 are used to construct the value of the control
179 ctrlp (OUT) A result parameter that will be assigned the address
180 of an LDAPControl structure that contains the
181 VirtualListViewRequest control created by this function.
182 The memory occupied by the LDAPControl structure
183 SHOULD be freed when it is no longer in use by
184 calling ldap_control_free().
189 VirtualListViewRequest ::= SEQUENCE {
190 beforeCount INTEGER (0 .. maxInt),
191 afterCount INTEGER (0 .. maxInt),
193 byoffset [0] SEQUENCE, {
194 offset INTEGER (0 .. maxInt),
195 contentCount INTEGER (0 .. maxInt) }
196 [1] greaterThanOrEqual assertionValue }
197 contextID OCTET STRING OPTIONAL }
200 Note: The first time the VLV control is created, the ldvlv_context
201 field of the LDAPVLVInfo structure should be set to NULL.
202 The context obtained from calling ldap_parse_vlv_control()
203 should be used as the context in the next ldap_create_vlv_control
209 ldap_create_vlv_control(
211 LDAPVLVInfo *vlvinfop,
212 LDAPControl **ctrlp )
216 if ( ctrlp == NULL ) {
217 ld->ld_errno = LDAP_PARAM_ERROR;
221 ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
222 if ( ld->ld_errno == LDAP_SUCCESS ) {
223 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
225 if ( ld->ld_errno == LDAP_SUCCESS ) {
226 (*ctrlp)->ldctl_value = value;
228 LDAP_FREE( value.bv_val );
237 ldap_parse_vlvresponse_control
239 Decode the Virtual List View control return information.
241 ld (IN) An LDAP session handle.
243 ctrl (IN) The address of the LDAPControl structure.
245 target_posp (OUT) This result parameter is filled in with the list
246 index of the target entry. If this parameter is
247 NULL, the target position is not returned.
249 list_countp (OUT) This result parameter is filled in with the server's
250 estimate of the size of the list. If this parameter
251 is NULL, the size is not returned.
253 contextp (OUT) This result parameter is filled in with the address
254 of a struct berval that contains the server-
255 generated context identifier if one was returned by
256 the server. If the server did not return a context
257 identifier, this parameter will be set to NULL, even
259 The returned context SHOULD be used in the next call
260 to create a VLV sort control. The struct berval
261 returned SHOULD be disposed of by calling ber_bvfree()
262 when it is no longer needed. If NULL is passed for
263 contextp, the context identifier is not returned.
265 errcodep (OUT) This result parameter is filled in with the VLV
266 result code. If this parameter is NULL, the result
267 code is not returned.
272 VirtualListViewResponse ::= SEQUENCE {
273 targetPosition INTEGER (0 .. maxInt),
274 contentCount INTEGER (0 .. maxInt),
275 virtualListViewResult ENUMERATED {
278 unwillingToPerform (53),
279 insufficientAccessRights (50),
281 timeLimitExceeded (3),
282 adminLimitExceeded (11),
283 sortControlMissing (60),
284 offsetRangeError (61),
286 contextID OCTET STRING OPTIONAL }
291 ldap_parse_vlvresponse_control(
294 ber_int_t *target_posp,
295 ber_int_t *list_countp,
296 struct berval **contextp,
297 ber_int_t *errcodep )
300 ber_int_t pos, count, err;
301 ber_tag_t tag, berTag;
304 assert( ld != NULL );
305 assert( LDAP_VALID( ld ) );
308 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
312 ld->ld_errno = LDAP_PARAM_ERROR;
313 return(ld->ld_errno);
316 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
317 /* Not VLV Response control */
318 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
319 return(ld->ld_errno);
322 /* Create a BerElement from the berval returned in the control. */
323 ber = ber_init(&ctrl->ldctl_value);
326 ld->ld_errno = LDAP_NO_MEMORY;
327 return(ld->ld_errno);
330 /* Extract the data returned in the control. */
331 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
333 if( tag == LBER_ERROR) {
335 ld->ld_errno = LDAP_DECODING_ERROR;
336 return(ld->ld_errno);
340 /* Since the context is the last item encoded, if caller doesn't want
341 it returned, don't decode it. */
343 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
344 tag = ber_scanf(ber, "tO", &berTag, contextp);
346 if( tag == LBER_ERROR) {
348 ld->ld_errno = LDAP_DECODING_ERROR;
349 return(ld->ld_errno);
356 /* Return data to the caller for items that were requested. */
357 if (target_posp) *target_posp = pos;
358 if (list_countp) *list_countp = count;
359 if (errcodep) *errcodep = err;
361 ld->ld_errno = LDAP_SUCCESS;
362 return(ld->ld_errno);