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( vlvinfop != NULL );
84 assert( ctrlp != NULL );
86 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
87 ld->ld_errno = LDAP_NO_MEMORY;
88 return(LDAP_NO_MEMORY);
91 tag = ber_printf(ber, "{ii" /*}*/,
92 vlvinfop->ldvlv_before_count,
93 vlvinfop->ldvlv_after_count);
94 if( tag == LBER_ERROR ) goto exit;
96 if (vlvinfop->ldvlv_attrvalue == NULL) {
97 tag = ber_printf(ber, "t{iiN}",
98 LDAP_VLVBYINDEX_IDENTIFIER,
99 vlvinfop->ldvlv_offset,
100 vlvinfop->ldvlv_count);
101 if( tag == LBER_ERROR ) goto exit;
104 tag = ber_printf(ber, "tO",
105 LDAP_VLVBYVALUE_IDENTIFIER,
106 vlvinfop->ldvlv_attrvalue);
107 if( tag == LBER_ERROR ) goto exit;
110 if (vlvinfop->ldvlv_context) {
111 tag = ber_printf(ber, "tO",
112 LDAP_VLVCONTEXT_IDENTIFIER,
113 vlvinfop->ldvlv_context);
114 if( tag == LBER_ERROR ) goto exit;
117 tag = ber_printf(ber, /*{*/ "N}");
118 if( tag == LBER_ERROR ) goto exit;
120 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
124 return(ld->ld_errno);
128 ld->ld_errno = LDAP_ENCODING_ERROR;
129 return(ld->ld_errno);
134 ldap_parse_vlv_control
136 Decode the Virtual List View control return information.
138 ld (IN) An LDAP session handle.
140 ctrls (IN) The address of a NULL-terminated array of
141 LDAPControl structures, typically obtained
142 by a call to ldap_parse_result().
144 target_posp (OUT) This result parameter is filled in with the list
145 index of the target entry. If this parameter is
146 NULL, the target position is not returned.
148 list_countp (OUT) This result parameter is filled in with the server's
149 estimate of the size of the list. If this parameter
150 is NULL, the size is not returned.
152 contextp (OUT) This result parameter is filled in with the address
153 of a struct berval that contains the server-
154 generated context identifier if one was returned by
155 the server. If the server did not return a context
156 identifier, this parameter will be set to NULL, even
158 The returned context SHOULD be used in the next call
159 to create a VLV sort control. The struct berval
160 returned SHOULD be disposed of by calling ber_bvfree()
161 when it is no longer needed. If NULL is passed for
162 contextp, the context identifier is not returned.
164 errcodep (OUT) This result parameter is filled in with the VLV
165 result code. If this parameter is NULL, the result
166 code is not returned.
171 VirtualListViewResponse ::= SEQUENCE {
172 targetPosition INTEGER (0 .. maxInt),
173 contentCount INTEGER (0 .. maxInt),
174 virtualListViewResult ENUMERATED {
177 unwillingToPerform (53),
178 insufficientAccessRights (50),
180 timeLimitExceeded (3),
181 adminLimitExceeded (11),
182 sortControlMissing (60),
183 offsetRangeError (61),
185 contextID OCTET STRING OPTIONAL }
190 ldap_parse_vlv_control(
193 unsigned long *target_posp,
194 unsigned long *list_countp,
195 struct berval **contextp,
199 LDAPControl *pControl;
201 unsigned long pos, count, err;
202 ber_tag_t tag, berTag;
205 assert( ld != NULL );
208 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
212 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
213 return(ld->ld_errno);
216 /* Search the list of control responses for a VLV control. */
217 for (i=0; ctrls[i]; i++) {
219 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
220 goto foundVLVControl;
223 /* No sort control was found. */
224 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
225 return(ld->ld_errno);
228 /* Create a BerElement from the berval returned in the control. */
229 ber = ber_init(&pControl->ldctl_value);
232 ld->ld_errno = LDAP_NO_MEMORY;
233 return(ld->ld_errno);
236 /* Extract the data returned in the control. */
237 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
239 if( tag == LBER_ERROR) {
241 ld->ld_errno = LDAP_DECODING_ERROR;
242 return(ld->ld_errno);
246 /* Since the context is the last item encoded, if caller doesn't want
247 it returned, don't decode it. */
249 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
250 tag = ber_scanf(ber, "tO", &berTag, contextp);
252 if( tag == LBER_ERROR) {
254 ld->ld_errno = LDAP_DECODING_ERROR;
255 return(ld->ld_errno);
262 /* Return data to the caller for items that were requested. */
267 *list_countp = count;
273 ld->ld_errno = LDAP_SUCCESS;
274 return(ld->ld_errno);