2 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
7 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
9 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
10 * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
11 * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
12 * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
13 * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
14 * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
15 * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
16 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
18 /* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
19 * can be found in the file "build/LICENSE-2.0.1" in this distribution
20 * of OpenLDAP Software.
26 #include <ac/stdlib.h>
27 #include <ac/string.h>
32 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
33 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
34 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
38 ldap_create_vlv_control
40 Create and encode the Virtual List View control.
42 ld (IN) An LDAP session handle, as obtained from a call to
45 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
46 are used to construct the value of the control
49 ctrlp (OUT) A result parameter that will be assigned the address
50 of an LDAPControl structure that contains the
51 VirtualListViewRequest control created by this function.
52 The memory occupied by the LDAPControl structure
53 SHOULD be freed when it is no longer in use by
54 calling ldap_control_free().
59 VirtualListViewRequest ::= SEQUENCE {
60 beforeCount INTEGER (0 .. maxInt),
61 afterCount INTEGER (0 .. maxInt),
63 byoffset [0] SEQUENCE, {
64 offset INTEGER (0 .. maxInt),
65 contentCount INTEGER (0 .. maxInt) }
66 [1] greaterThanOrEqual assertionValue }
67 contextID OCTET STRING OPTIONAL }
70 Note: The first time the VLV control is created, the ldvlv_context
71 field of the LDAPVLVInfo structure should be set to NULL.
72 The context obtained from calling ldap_parse_vlv_control()
73 should be used as the context in the next ldap_create_vlv_control
79 ldap_create_vlv_control( LDAP *ld,
80 LDAPVLVInfo *vlvinfop,
87 assert( LDAP_VALID( ld ) );
88 assert( vlvinfop != NULL );
89 assert( ctrlp != NULL );
91 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
92 ld->ld_errno = LDAP_NO_MEMORY;
93 return(LDAP_NO_MEMORY);
96 tag = ber_printf(ber, "{ii" /*}*/,
97 vlvinfop->ldvlv_before_count,
98 vlvinfop->ldvlv_after_count);
99 if( tag == LBER_ERROR ) goto exit;
101 if (vlvinfop->ldvlv_attrvalue == NULL) {
102 tag = ber_printf(ber, "t{iiN}",
103 LDAP_VLVBYINDEX_IDENTIFIER,
104 vlvinfop->ldvlv_offset,
105 vlvinfop->ldvlv_count);
106 if( tag == LBER_ERROR ) goto exit;
109 tag = ber_printf(ber, "tO",
110 LDAP_VLVBYVALUE_IDENTIFIER,
111 vlvinfop->ldvlv_attrvalue);
112 if( tag == LBER_ERROR ) goto exit;
115 if (vlvinfop->ldvlv_context) {
116 tag = ber_printf(ber, "tO",
117 LDAP_VLVCONTEXT_IDENTIFIER,
118 vlvinfop->ldvlv_context);
119 if( tag == LBER_ERROR ) goto exit;
122 tag = ber_printf(ber, /*{*/ "N}");
123 if( tag == LBER_ERROR ) goto exit;
125 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
129 return(ld->ld_errno);
133 ld->ld_errno = LDAP_ENCODING_ERROR;
134 return(ld->ld_errno);
139 ldap_parse_vlv_control
141 Decode the Virtual List View control return information.
143 ld (IN) An LDAP session handle.
145 ctrls (IN) The address of a NULL-terminated array of
146 LDAPControl structures, typically obtained
147 by a call to ldap_parse_result().
149 target_posp (OUT) This result parameter is filled in with the list
150 index of the target entry. If this parameter is
151 NULL, the target position is not returned.
153 list_countp (OUT) This result parameter is filled in with the server's
154 estimate of the size of the list. If this parameter
155 is NULL, the size is not returned.
157 contextp (OUT) This result parameter is filled in with the address
158 of a struct berval that contains the server-
159 generated context identifier if one was returned by
160 the server. If the server did not return a context
161 identifier, this parameter will be set to NULL, even
163 The returned context SHOULD be used in the next call
164 to create a VLV sort control. The struct berval
165 returned SHOULD be disposed of by calling ber_bvfree()
166 when it is no longer needed. If NULL is passed for
167 contextp, the context identifier is not returned.
169 errcodep (OUT) This result parameter is filled in with the VLV
170 result code. If this parameter is NULL, the result
171 code is not returned.
176 VirtualListViewResponse ::= SEQUENCE {
177 targetPosition INTEGER (0 .. maxInt),
178 contentCount INTEGER (0 .. maxInt),
179 virtualListViewResult ENUMERATED {
182 unwillingToPerform (53),
183 insufficientAccessRights (50),
185 timeLimitExceeded (3),
186 adminLimitExceeded (11),
187 sortControlMissing (60),
188 offsetRangeError (61),
190 contextID OCTET STRING OPTIONAL }
195 ldap_parse_vlv_control(
198 unsigned long *target_posp,
199 unsigned long *list_countp,
200 struct berval **contextp,
204 LDAPControl *pControl;
206 unsigned long pos, count, err;
207 ber_tag_t tag, berTag;
210 assert( ld != NULL );
211 assert( LDAP_VALID( ld ) );
214 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
218 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
219 return(ld->ld_errno);
222 /* Search the list of control responses for a VLV control. */
223 for (i=0; ctrls[i]; i++) {
225 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
226 goto foundVLVControl;
229 /* No sort control was found. */
230 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
231 return(ld->ld_errno);
234 /* Create a BerElement from the berval returned in the control. */
235 ber = ber_init(&pControl->ldctl_value);
238 ld->ld_errno = LDAP_NO_MEMORY;
239 return(ld->ld_errno);
242 /* Extract the data returned in the control. */
243 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
245 if( tag == LBER_ERROR) {
247 ld->ld_errno = LDAP_DECODING_ERROR;
248 return(ld->ld_errno);
252 /* Since the context is the last item encoded, if caller doesn't want
253 it returned, don't decode it. */
255 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
256 tag = ber_scanf(ber, "tO", &berTag, contextp);
258 if( tag == LBER_ERROR) {
260 ld->ld_errno = LDAP_DECODING_ERROR;
261 return(ld->ld_errno);
268 /* Return data to the caller for items that were requested. */
273 *list_countp = count;
279 ld->ld_errno = LDAP_SUCCESS;
280 return(ld->ld_errno);