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 )
217 if ( ctrlp == NULL ) {
218 ld->ld_errno = LDAP_PARAM_ERROR;
222 ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
223 if ( ld->ld_errno == LDAP_SUCCESS ) {
224 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
225 ld->ld_errno = LDAP_NO_MEMORY;
226 return LDAP_NO_MEMORY;
229 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
231 if ( ld->ld_errno == LDAP_SUCCESS ) {
232 (*ctrlp)->ldctl_value = value;
234 LDAP_FREE( value.bv_val );
244 ldap_parse_vlvresponse_control
246 Decode the Virtual List View control return information.
248 ld (IN) An LDAP session handle.
250 ctrl (IN) The address of the LDAPControl structure.
252 target_posp (OUT) This result parameter is filled in with the list
253 index of the target entry. If this parameter is
254 NULL, the target position is not returned.
256 list_countp (OUT) This result parameter is filled in with the server's
257 estimate of the size of the list. If this parameter
258 is NULL, the size is not returned.
260 contextp (OUT) This result parameter is filled in with the address
261 of a struct berval that contains the server-
262 generated context identifier if one was returned by
263 the server. If the server did not return a context
264 identifier, this parameter will be set to NULL, even
266 The returned context SHOULD be used in the next call
267 to create a VLV sort control. The struct berval
268 returned SHOULD be disposed of by calling ber_bvfree()
269 when it is no longer needed. If NULL is passed for
270 contextp, the context identifier is not returned.
272 errcodep (OUT) This result parameter is filled in with the VLV
273 result code. If this parameter is NULL, the result
274 code is not returned.
279 VirtualListViewResponse ::= SEQUENCE {
280 targetPosition INTEGER (0 .. maxInt),
281 contentCount INTEGER (0 .. maxInt),
282 virtualListViewResult ENUMERATED {
285 unwillingToPerform (53),
286 insufficientAccessRights (50),
288 timeLimitExceeded (3),
289 adminLimitExceeded (11),
290 sortControlMissing (60),
291 offsetRangeError (61),
293 contextID OCTET STRING OPTIONAL }
298 ldap_parse_vlvresponse_control(
301 ber_int_t *target_posp,
302 ber_int_t *list_countp,
303 struct berval **contextp,
304 ber_int_t *errcodep )
307 ber_int_t pos, count, err;
308 ber_tag_t tag, berTag;
311 assert( ld != NULL );
312 assert( LDAP_VALID( ld ) );
315 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
319 ld->ld_errno = LDAP_PARAM_ERROR;
320 return(ld->ld_errno);
323 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
324 /* Not VLV Response control */
325 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
326 return(ld->ld_errno);
329 /* Create a BerElement from the berval returned in the control. */
330 ber = ber_init(&ctrl->ldctl_value);
333 ld->ld_errno = LDAP_NO_MEMORY;
334 return(ld->ld_errno);
337 /* Extract the data returned in the control. */
338 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
340 if( tag == LBER_ERROR) {
342 ld->ld_errno = LDAP_DECODING_ERROR;
343 return(ld->ld_errno);
347 /* Since the context is the last item encoded, if caller doesn't want
348 it returned, don't decode it. */
350 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
351 tag = ber_scanf(ber, "tO", &berTag, contextp);
353 if( tag == LBER_ERROR) {
355 ld->ld_errno = LDAP_DECODING_ERROR;
356 return(ld->ld_errno);
363 /* Return data to the caller for items that were requested. */
364 if (target_posp) *target_posp = pos;
365 if (list_countp) *list_countp = count;
366 if (errcodep) *errcodep = err;
368 ld->ld_errno = LDAP_SUCCESS;
369 return(ld->ld_errno);