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.
23 * Portions Copyright (C) The Internet Society (1997)
24 * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
30 #include <ac/stdlib.h>
31 #include <ac/string.h>
36 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
37 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
38 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
42 ldap_create_vlv_control
44 Create and encode the Virtual List View control.
46 ld (IN) An LDAP session handle, as obtained from a call to
49 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
50 are used to construct the value of the control
53 ctrlp (OUT) A result parameter that will be assigned the address
54 of an LDAPControl structure that contains the
55 VirtualListViewRequest control created by this function.
56 The memory occupied by the LDAPControl structure
57 SHOULD be freed when it is no longer in use by
58 calling ldap_control_free().
63 VirtualListViewRequest ::= SEQUENCE {
64 beforeCount INTEGER (0 .. maxInt),
65 afterCount INTEGER (0 .. maxInt),
67 byoffset [0] SEQUENCE, {
68 offset INTEGER (0 .. maxInt),
69 contentCount INTEGER (0 .. maxInt) }
70 [1] greaterThanOrEqual assertionValue }
71 contextID OCTET STRING OPTIONAL }
74 Note: The first time the VLV control is created, the ldvlv_context
75 field of the LDAPVLVInfo structure should be set to NULL.
76 The context obtained from calling ldap_parse_vlv_control()
77 should be used as the context in the next ldap_create_vlv_control
83 ldap_create_vlv_control( LDAP *ld,
84 LDAPVLVInfo *vlvinfop,
91 assert( LDAP_VALID( ld ) );
92 assert( vlvinfop != NULL );
93 assert( ctrlp != NULL );
95 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
96 ld->ld_errno = LDAP_NO_MEMORY;
97 return(LDAP_NO_MEMORY);
100 tag = ber_printf(ber, "{ii" /*}*/,
101 vlvinfop->ldvlv_before_count,
102 vlvinfop->ldvlv_after_count);
103 if( tag == LBER_ERROR ) goto exit;
105 if (vlvinfop->ldvlv_attrvalue == NULL) {
106 tag = ber_printf(ber, "t{iiN}",
107 LDAP_VLVBYINDEX_IDENTIFIER,
108 vlvinfop->ldvlv_offset,
109 vlvinfop->ldvlv_count);
110 if( tag == LBER_ERROR ) goto exit;
113 tag = ber_printf(ber, "tO",
114 LDAP_VLVBYVALUE_IDENTIFIER,
115 vlvinfop->ldvlv_attrvalue);
116 if( tag == LBER_ERROR ) goto exit;
119 if (vlvinfop->ldvlv_context) {
120 tag = ber_printf(ber, "tO",
121 LDAP_VLVCONTEXT_IDENTIFIER,
122 vlvinfop->ldvlv_context);
123 if( tag == LBER_ERROR ) goto exit;
126 tag = ber_printf(ber, /*{*/ "N}");
127 if( tag == LBER_ERROR ) goto exit;
129 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
133 return(ld->ld_errno);
137 ld->ld_errno = LDAP_ENCODING_ERROR;
138 return(ld->ld_errno);
143 ldap_parse_vlv_control
145 Decode the Virtual List View control return information.
147 ld (IN) An LDAP session handle.
149 ctrls (IN) The address of a NULL-terminated array of
150 LDAPControl structures, typically obtained
151 by a call to ldap_parse_result().
153 target_posp (OUT) This result parameter is filled in with the list
154 index of the target entry. If this parameter is
155 NULL, the target position is not returned.
157 list_countp (OUT) This result parameter is filled in with the server's
158 estimate of the size of the list. If this parameter
159 is NULL, the size is not returned.
161 contextp (OUT) This result parameter is filled in with the address
162 of a struct berval that contains the server-
163 generated context identifier if one was returned by
164 the server. If the server did not return a context
165 identifier, this parameter will be set to NULL, even
167 The returned context SHOULD be used in the next call
168 to create a VLV sort control. The struct berval
169 returned SHOULD be disposed of by calling ber_bvfree()
170 when it is no longer needed. If NULL is passed for
171 contextp, the context identifier is not returned.
173 errcodep (OUT) This result parameter is filled in with the VLV
174 result code. If this parameter is NULL, the result
175 code is not returned.
180 VirtualListViewResponse ::= SEQUENCE {
181 targetPosition INTEGER (0 .. maxInt),
182 contentCount INTEGER (0 .. maxInt),
183 virtualListViewResult ENUMERATED {
186 unwillingToPerform (53),
187 insufficientAccessRights (50),
189 timeLimitExceeded (3),
190 adminLimitExceeded (11),
191 sortControlMissing (60),
192 offsetRangeError (61),
194 contextID OCTET STRING OPTIONAL }
199 ldap_parse_vlv_control(
202 unsigned long *target_posp,
203 unsigned long *list_countp,
204 struct berval **contextp,
208 LDAPControl *pControl;
210 unsigned long pos, count, err;
211 ber_tag_t tag, berTag;
214 assert( ld != NULL );
215 assert( LDAP_VALID( ld ) );
218 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
222 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
223 return(ld->ld_errno);
226 /* Search the list of control responses for a VLV control. */
227 for (i=0; ctrls[i]; i++) {
229 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
230 goto foundVLVControl;
233 /* No sort control was found. */
234 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
235 return(ld->ld_errno);
238 /* Create a BerElement from the berval returned in the control. */
239 ber = ber_init(&pControl->ldctl_value);
242 ld->ld_errno = LDAP_NO_MEMORY;
243 return(ld->ld_errno);
246 /* Extract the data returned in the control. */
247 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
249 if( tag == LBER_ERROR) {
251 ld->ld_errno = LDAP_DECODING_ERROR;
252 return(ld->ld_errno);
256 /* Since the context is the last item encoded, if caller doesn't want
257 it returned, don't decode it. */
259 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
260 tag = ber_scanf(ber, "tO", &berTag, contextp);
262 if( tag == LBER_ERROR) {
264 ld->ld_errno = LDAP_DECODING_ERROR;
265 return(ld->ld_errno);
272 /* Return data to the caller for items that were requested. */
277 *list_countp = count;
283 ld->ld_errno = LDAP_SUCCESS;
284 return(ld->ld_errno);