2 * Copyright 1998-2000 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>
29 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
30 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
31 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
35 ldap_create_vlv_control
37 Create and encode the Virtual List View control.
39 ld (IN) An LDAP session handle, as obtained from a call to
42 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
43 are used to construct the value of the control
46 ctrlp (OUT) A result parameter that will be assigned the address
47 of an LDAPControl structure that contains the
48 VirtualListViewRequest control created by this function.
49 The memory occupied by the LDAPControl structure
50 SHOULD be freed when it is no longer in use by
51 calling ldap_control_free().
56 VirtualListViewRequest ::= SEQUENCE {
57 beforeCount INTEGER (0 .. maxInt),
58 afterCount INTEGER (0 .. maxInt),
60 byoffset [0] SEQUENCE, {
61 offset INTEGER (0 .. maxInt),
62 contentCount INTEGER (0 .. maxInt) }
63 [1] greaterThanOrEqual assertionValue }
64 contextID OCTET STRING OPTIONAL }
67 Note: The first time the VLV control is created, the ldvlv_context
68 field of the LDAPVLVInfo structure should be set to NULL.
69 The context obtained from calling ldap_parse_vlv_control()
70 should be used as the context in the next ldap_create_vlv_control
76 ldap_create_vlv_control( LDAP *ld,
77 LDAPVLVInfo *vlvinfop,
83 if ( (ld==NULL) || (vlvinfop==NULL) || (ctrlp == NULL) ) {
84 ld->ld_errno = LDAP_PARAM_ERROR;
88 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
89 ld->ld_errno = LDAP_NO_MEMORY;
90 return(LDAP_NO_MEMORY);
93 tag = ber_printf(ber, "{ii" /*}*/,
94 vlvinfop->ldvlv_before_count,
95 vlvinfop->ldvlv_after_count);
96 if( tag == LBER_ERROR ) goto exit;
98 if (vlvinfop->ldvlv_attrvalue == NULL) {
99 tag = ber_printf(ber, "t{ii}",
100 LDAP_VLVBYINDEX_IDENTIFIER,
101 vlvinfop->ldvlv_offset,
102 vlvinfop->ldvlv_count);
103 if( tag == LBER_ERROR ) goto exit;
106 tag = ber_printf(ber, "tO",
107 LDAP_VLVBYVALUE_IDENTIFIER,
108 vlvinfop->ldvlv_attrvalue);
109 if( tag == LBER_ERROR ) goto exit;
112 if (vlvinfop->ldvlv_context) {
113 tag = ber_printf(ber, "tO",
114 LDAP_VLVCONTEXT_IDENTIFIER,
115 vlvinfop->ldvlv_context);
116 if( tag == LBER_ERROR ) goto exit;
119 tag = ber_printf(ber, /*{*/ "}");
120 if( tag == LBER_ERROR ) goto exit;
122 ld->ld_errno = ldap_int_create_control(
123 LDAP_CONTROL_VLVREQUEST, ber, 1, ctrlp);
126 return(ld->ld_errno);
130 ld->ld_errno = LDAP_ENCODING_ERROR;
131 return(ld->ld_errno);
136 ldap_parse_vlv_control
138 Decode the Virtual List View control return information.
140 ld (IN) An LDAP session handle.
142 ctrls (IN) The address of a NULL-terminated array of
143 LDAPControl structures, typically obtained
144 by a call to ldap_parse_result().
146 target_posp (OUT) This result parameter is filled in with the list
147 index of the target entry. If this parameter is
148 NULL, the target position is not returned.
150 list_countp (OUT) This result parameter is filled in with the server's
151 estimate of the size of the list. If this parameter
152 is NULL, the size is not returned.
154 contextp (OUT) This result parameter is filled in with the address
155 of a struct berval that contains the server-
156 generated context identifier if one was returned by
157 the server. If the server did not return a context
158 identifier, this parameter will be set to NULL, even
160 The returned context SHOULD be used in the next call
161 to create a VLV sort control. The struct berval
162 returned SHOULD be disposed of by calling ber_bvfree()
163 when it is no longer needed. If NULL is passed for
164 contextp, the context identifier is not returned.
166 errcodep (OUT) This result parameter is filled in with the VLV
167 result code. If this parameter is NULL, the result
168 code is not returned.
173 VirtualListViewResponse ::= SEQUENCE {
174 targetPosition INTEGER (0 .. maxInt),
175 contentCount INTEGER (0 .. maxInt),
176 virtualListViewResult ENUMERATED {
179 unwillingToPerform (53),
180 insufficientAccessRights (50),
182 timeLimitExceeded (3),
183 adminLimitExceeded (11),
184 sortControlMissing (60),
185 offsetRangeError (61),
187 contextID OCTET STRING OPTIONAL }
192 ldap_parse_vlv_control(
195 unsigned long *target_posp,
196 unsigned long *list_countp,
197 struct berval **contextp,
201 LDAPControl *pControl;
203 unsigned long pos, count, err;
204 ber_tag_t tag, berTag;
208 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
212 ld->ld_errno = LDAP_PARAM_ERROR;
213 return(ld->ld_errno);
217 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
218 return(ld->ld_errno);
221 /* Search the list of control responses for a VLV control. */
222 for (i=0; ctrls[i]; i++) {
224 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
225 goto foundVLVControl;
228 /* No sort control was found. */
229 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
230 return(ld->ld_errno);
233 /* Create a BerElement from the berval returned in the control. */
234 ber = ber_init(&pControl->ldctl_value);
237 ld->ld_errno = LDAP_NO_MEMORY;
238 return(ld->ld_errno);
241 /* Extract the data returned in the control. */
242 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
244 if( tag == LBER_ERROR) {
246 ld->ld_errno = LDAP_DECODING_ERROR;
247 return(ld->ld_errno);
251 /* Since the context is the last item encoded, if caller doesn't want
252 it returned, don't decode it. */
254 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
255 tag = ber_scanf(ber, "tO", &berTag, contextp);
257 if( tag == LBER_ERROR) {
259 ld->ld_errno = LDAP_DECODING_ERROR;
260 return(ld->ld_errno);
267 /* Return data to the caller for items that were requested. */
272 *list_countp = count;
278 ld->ld_errno = LDAP_SUCCESS;
279 return(ld->ld_errno);