2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2012 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.
34 #include <ac/stdlib.h>
35 #include <ac/string.h>
40 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
41 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
42 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
46 ldap_create_vlv_control
48 Create and encode the Virtual List View control.
50 ld (IN) An LDAP session handle.
52 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
53 are used to construct the value of the control
56 value (OUT) A struct berval that contains the value to be assigned to the ldctl_value member
57 of an LDAPControl structure that contains the
58 VirtualListViewRequest control.
59 The bv_val member of the berval structure
60 SHOULD be freed when it is no longer in use by
61 calling ldap_memfree().
66 VirtualListViewRequest ::= SEQUENCE {
67 beforeCount INTEGER (0 .. maxInt),
68 afterCount INTEGER (0 .. maxInt),
70 byoffset [0] SEQUENCE, {
71 offset INTEGER (0 .. maxInt),
72 contentCount INTEGER (0 .. maxInt) }
73 [1] greaterThanOrEqual assertionValue }
74 contextID OCTET STRING OPTIONAL }
77 Note: The first time the VLV control is created, the ldvlv_context
78 field of the LDAPVLVInfo structure should be set to NULL.
79 The context obtained from calling ldap_parse_vlv_control()
80 should be used as the context in the next ldap_create_vlv_control
86 ldap_create_vlv_control_value(
88 LDAPVLVInfo *vlvinfop,
89 struct berval *value )
94 if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
96 ld->ld_errno = LDAP_PARAM_ERROR;
97 return LDAP_PARAM_ERROR;
100 assert( LDAP_VALID( ld ) );
102 value->bv_val = NULL;
104 ld->ld_errno = LDAP_SUCCESS;
106 ber = ldap_alloc_ber_with_options( ld );
108 ld->ld_errno = LDAP_NO_MEMORY;
112 tag = ber_printf( ber, "{ii" /*}*/,
113 vlvinfop->ldvlv_before_count,
114 vlvinfop->ldvlv_after_count );
115 if ( tag == LBER_ERROR ) {
119 if ( vlvinfop->ldvlv_attrvalue == NULL ) {
120 tag = ber_printf( ber, "t{iiN}",
121 LDAP_VLVBYINDEX_IDENTIFIER,
122 vlvinfop->ldvlv_offset,
123 vlvinfop->ldvlv_count );
124 if ( tag == LBER_ERROR ) {
129 tag = ber_printf( ber, "tO",
130 LDAP_VLVBYVALUE_IDENTIFIER,
131 vlvinfop->ldvlv_attrvalue );
132 if ( tag == LBER_ERROR ) {
137 if ( vlvinfop->ldvlv_context ) {
138 tag = ber_printf( ber, "tO",
139 LDAP_VLVCONTEXT_IDENTIFIER,
140 vlvinfop->ldvlv_context );
141 if ( tag == LBER_ERROR ) {
146 tag = ber_printf( ber, /*{*/ "N}" );
147 if ( tag == LBER_ERROR ) {
151 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
152 ld->ld_errno = LDAP_NO_MEMORY;
157 ld->ld_errno = LDAP_ENCODING_ERROR;
168 ldap_create_vlv_control
170 Create and encode the Virtual List View control.
172 ld (IN) An LDAP session handle.
174 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
175 are used to construct the value of the control
178 ctrlp (OUT) A result parameter that will be assigned the address
179 of an LDAPControl structure that contains the
180 VirtualListViewRequest control created by this function.
181 The memory occupied by the LDAPControl structure
182 SHOULD be freed when it is no longer in use by
183 calling ldap_control_free().
188 VirtualListViewRequest ::= SEQUENCE {
189 beforeCount INTEGER (0 .. maxInt),
190 afterCount INTEGER (0 .. maxInt),
192 byoffset [0] SEQUENCE, {
193 offset INTEGER (0 .. maxInt),
194 contentCount INTEGER (0 .. maxInt) }
195 [1] greaterThanOrEqual assertionValue }
196 contextID OCTET STRING OPTIONAL }
199 Note: The first time the VLV control is created, the ldvlv_context
200 field of the LDAPVLVInfo structure should be set to NULL.
201 The context obtained from calling ldap_parse_vlv_control()
202 should be used as the context in the next ldap_create_vlv_control
208 ldap_create_vlv_control(
210 LDAPVLVInfo *vlvinfop,
211 LDAPControl **ctrlp )
215 if ( ctrlp == NULL ) {
216 ld->ld_errno = LDAP_PARAM_ERROR;
220 ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
221 if ( ld->ld_errno == LDAP_SUCCESS ) {
223 ld->ld_errno = ldap_control_create( LDAP_CONTROL_VLVREQUEST,
224 1, &value, 0, ctrlp );
225 if ( ld->ld_errno != LDAP_SUCCESS ) {
226 LDAP_FREE( value.bv_val );
235 ldap_parse_vlvresponse_control
237 Decode the Virtual List View control return information.
239 ld (IN) An LDAP session handle.
241 ctrl (IN) The address of the LDAPControl structure.
243 target_posp (OUT) This result parameter is filled in with the list
244 index of the target entry. If this parameter is
245 NULL, the target position is not returned.
247 list_countp (OUT) This result parameter is filled in with the server's
248 estimate of the size of the list. If this parameter
249 is NULL, the size is not returned.
251 contextp (OUT) This result parameter is filled in with the address
252 of a struct berval that contains the server-
253 generated context identifier if one was returned by
254 the server. If the server did not return a context
255 identifier, this parameter will be set to NULL, even
257 The returned context SHOULD be used in the next call
258 to create a VLV sort control. The struct berval
259 returned SHOULD be disposed of by calling ber_bvfree()
260 when it is no longer needed. If NULL is passed for
261 contextp, the context identifier is not returned.
263 errcodep (OUT) This result parameter is filled in with the VLV
264 result code. If this parameter is NULL, the result
265 code is not returned.
270 VirtualListViewResponse ::= SEQUENCE {
271 targetPosition INTEGER (0 .. maxInt),
272 contentCount INTEGER (0 .. maxInt),
273 virtualListViewResult ENUMERATED {
276 unwillingToPerform (53),
277 insufficientAccessRights (50),
279 timeLimitExceeded (3),
280 adminLimitExceeded (11),
281 sortControlMissing (60),
282 offsetRangeError (61),
284 contextID OCTET STRING OPTIONAL }
289 ldap_parse_vlvresponse_control(
292 ber_int_t *target_posp,
293 ber_int_t *list_countp,
294 struct berval **contextp,
295 ber_int_t *errcodep )
298 ber_int_t pos, count, err;
299 ber_tag_t tag, berTag;
302 assert( ld != NULL );
303 assert( LDAP_VALID( ld ) );
306 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
310 ld->ld_errno = LDAP_PARAM_ERROR;
311 return(ld->ld_errno);
314 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
315 /* Not VLV Response control */
316 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
317 return(ld->ld_errno);
320 /* Create a BerElement from the berval returned in the control. */
321 ber = ber_init(&ctrl->ldctl_value);
324 ld->ld_errno = LDAP_NO_MEMORY;
325 return(ld->ld_errno);
328 /* Extract the data returned in the control. */
329 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
331 if( tag == LBER_ERROR) {
333 ld->ld_errno = LDAP_DECODING_ERROR;
334 return(ld->ld_errno);
338 /* Since the context is the last item encoded, if caller doesn't want
339 it returned, don't decode it. */
341 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
342 tag = ber_scanf(ber, "tO", &berTag, contextp);
344 if( tag == LBER_ERROR) {
346 ld->ld_errno = LDAP_DECODING_ERROR;
347 return(ld->ld_errno);
354 /* Return data to the caller for items that were requested. */
355 if (target_posp) *target_posp = pos;
356 if (list_countp) *list_countp = count;
357 if (errcodep) *errcodep = err;
359 ld->ld_errno = LDAP_SUCCESS;
360 return(ld->ld_errno);