2 * Copyright 1998-2002 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.
22 #include <ac/stdlib.h>
23 #include <ac/string.h>
28 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
29 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
30 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
34 ldap_create_vlv_control
36 Create and encode the Virtual List View control.
38 ld (IN) An LDAP session handle, as obtained from a call to
41 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
42 are used to construct the value of the control
45 ctrlp (OUT) A result parameter that will be assigned the address
46 of an LDAPControl structure that contains the
47 VirtualListViewRequest control created by this function.
48 The memory occupied by the LDAPControl structure
49 SHOULD be freed when it is no longer in use by
50 calling ldap_control_free().
55 VirtualListViewRequest ::= SEQUENCE {
56 beforeCount INTEGER (0 .. maxInt),
57 afterCount INTEGER (0 .. maxInt),
59 byoffset [0] SEQUENCE, {
60 offset INTEGER (0 .. maxInt),
61 contentCount INTEGER (0 .. maxInt) }
62 [1] greaterThanOrEqual assertionValue }
63 contextID OCTET STRING OPTIONAL }
66 Note: The first time the VLV control is created, the ldvlv_context
67 field of the LDAPVLVInfo structure should be set to NULL.
68 The context obtained from calling ldap_parse_vlv_control()
69 should be used as the context in the next ldap_create_vlv_control
75 ldap_create_vlv_control( LDAP *ld,
76 LDAPVLVInfo *vlvinfop,
83 assert( LDAP_VALID( ld ) );
84 assert( vlvinfop != NULL );
85 assert( ctrlp != NULL );
87 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
88 ld->ld_errno = LDAP_NO_MEMORY;
89 return(LDAP_NO_MEMORY);
92 tag = ber_printf(ber, "{ii" /*}*/,
93 vlvinfop->ldvlv_before_count,
94 vlvinfop->ldvlv_after_count);
95 if( tag == LBER_ERROR ) goto exit;
97 if (vlvinfop->ldvlv_attrvalue == NULL) {
98 tag = ber_printf(ber, "t{iiN}",
99 LDAP_VLVBYINDEX_IDENTIFIER,
100 vlvinfop->ldvlv_offset,
101 vlvinfop->ldvlv_count);
102 if( tag == LBER_ERROR ) goto exit;
105 tag = ber_printf(ber, "tO",
106 LDAP_VLVBYVALUE_IDENTIFIER,
107 vlvinfop->ldvlv_attrvalue);
108 if( tag == LBER_ERROR ) goto exit;
111 if (vlvinfop->ldvlv_context) {
112 tag = ber_printf(ber, "tO",
113 LDAP_VLVCONTEXT_IDENTIFIER,
114 vlvinfop->ldvlv_context);
115 if( tag == LBER_ERROR ) goto exit;
118 tag = ber_printf(ber, /*{*/ "N}");
119 if( tag == LBER_ERROR ) goto exit;
121 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
125 return(ld->ld_errno);
129 ld->ld_errno = LDAP_ENCODING_ERROR;
130 return(ld->ld_errno);
135 ldap_parse_vlv_control
137 Decode the Virtual List View control return information.
139 ld (IN) An LDAP session handle.
141 ctrls (IN) The address of a NULL-terminated array of
142 LDAPControl structures, typically obtained
143 by a call to ldap_parse_result().
145 target_posp (OUT) This result parameter is filled in with the list
146 index of the target entry. If this parameter is
147 NULL, the target position is not returned.
149 list_countp (OUT) This result parameter is filled in with the server's
150 estimate of the size of the list. If this parameter
151 is NULL, the size is not returned.
153 contextp (OUT) This result parameter is filled in with the address
154 of a struct berval that contains the server-
155 generated context identifier if one was returned by
156 the server. If the server did not return a context
157 identifier, this parameter will be set to NULL, even
159 The returned context SHOULD be used in the next call
160 to create a VLV sort control. The struct berval
161 returned SHOULD be disposed of by calling ber_bvfree()
162 when it is no longer needed. If NULL is passed for
163 contextp, the context identifier is not returned.
165 errcodep (OUT) This result parameter is filled in with the VLV
166 result code. If this parameter is NULL, the result
167 code is not returned.
172 VirtualListViewResponse ::= SEQUENCE {
173 targetPosition INTEGER (0 .. maxInt),
174 contentCount INTEGER (0 .. maxInt),
175 virtualListViewResult ENUMERATED {
178 unwillingToPerform (53),
179 insufficientAccessRights (50),
181 timeLimitExceeded (3),
182 adminLimitExceeded (11),
183 sortControlMissing (60),
184 offsetRangeError (61),
186 contextID OCTET STRING OPTIONAL }
191 ldap_parse_vlv_control(
194 unsigned long *target_posp,
195 unsigned long *list_countp,
196 struct berval **contextp,
200 LDAPControl *pControl;
202 unsigned long pos, count, err;
203 ber_tag_t tag, berTag;
206 assert( ld != NULL );
207 assert( LDAP_VALID( ld ) );
210 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
214 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
215 return(ld->ld_errno);
218 /* Search the list of control responses for a VLV control. */
219 for (i=0; ctrls[i]; i++) {
221 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
222 goto foundVLVControl;
225 /* No sort control was found. */
226 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
227 return(ld->ld_errno);
230 /* Create a BerElement from the berval returned in the control. */
231 ber = ber_init(&pControl->ldctl_value);
234 ld->ld_errno = LDAP_NO_MEMORY;
235 return(ld->ld_errno);
238 /* Extract the data returned in the control. */
239 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
241 if( tag == LBER_ERROR) {
243 ld->ld_errno = LDAP_DECODING_ERROR;
244 return(ld->ld_errno);
248 /* Since the context is the last item encoded, if caller doesn't want
249 it returned, don't decode it. */
251 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
252 tag = ber_scanf(ber, "tO", &berTag, contextp);
254 if( tag == LBER_ERROR) {
256 ld->ld_errno = LDAP_DECODING_ERROR;
257 return(ld->ld_errno);
264 /* Return data to the caller for items that were requested. */
269 *list_countp = count;
275 ld->ld_errno = LDAP_SUCCESS;
276 return(ld->ld_errno);