2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2003 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* Portions Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
17 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
18 * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
19 * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
20 * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
21 * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
22 * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
23 * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
24 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
26 * Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
27 * can be found in the file "build/LICENSE-2.0.1" in this distribution
28 * of OpenLDAP Software.
30 /* Portions Copyright (C) The Internet Society (1997)
31 * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
37 #include <ac/stdlib.h>
38 #include <ac/string.h>
43 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
44 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
45 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
49 ldap_create_vlv_control
51 Create and encode the Virtual List View control.
53 ld (IN) An LDAP session handle, as obtained from a call to
56 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
57 are used to construct the value of the control
60 ctrlp (OUT) A result parameter that will be assigned the address
61 of an LDAPControl structure that contains the
62 VirtualListViewRequest control created by this function.
63 The memory occupied by the LDAPControl structure
64 SHOULD be freed when it is no longer in use by
65 calling ldap_control_free().
70 VirtualListViewRequest ::= SEQUENCE {
71 beforeCount INTEGER (0 .. maxInt),
72 afterCount INTEGER (0 .. maxInt),
74 byoffset [0] SEQUENCE, {
75 offset INTEGER (0 .. maxInt),
76 contentCount INTEGER (0 .. maxInt) }
77 [1] greaterThanOrEqual assertionValue }
78 contextID OCTET STRING OPTIONAL }
81 Note: The first time the VLV control is created, the ldvlv_context
82 field of the LDAPVLVInfo structure should be set to NULL.
83 The context obtained from calling ldap_parse_vlv_control()
84 should be used as the context in the next ldap_create_vlv_control
90 ldap_create_vlv_control( LDAP *ld,
91 LDAPVLVInfo *vlvinfop,
98 assert( LDAP_VALID( ld ) );
99 assert( vlvinfop != NULL );
100 assert( ctrlp != NULL );
102 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
103 ld->ld_errno = LDAP_NO_MEMORY;
104 return(LDAP_NO_MEMORY);
107 tag = ber_printf(ber, "{ii" /*}*/,
108 vlvinfop->ldvlv_before_count,
109 vlvinfop->ldvlv_after_count);
110 if( tag == LBER_ERROR ) goto exit;
112 if (vlvinfop->ldvlv_attrvalue == NULL) {
113 tag = ber_printf(ber, "t{iiN}",
114 LDAP_VLVBYINDEX_IDENTIFIER,
115 vlvinfop->ldvlv_offset,
116 vlvinfop->ldvlv_count);
117 if( tag == LBER_ERROR ) goto exit;
120 tag = ber_printf(ber, "tO",
121 LDAP_VLVBYVALUE_IDENTIFIER,
122 vlvinfop->ldvlv_attrvalue);
123 if( tag == LBER_ERROR ) goto exit;
126 if (vlvinfop->ldvlv_context) {
127 tag = ber_printf(ber, "tO",
128 LDAP_VLVCONTEXT_IDENTIFIER,
129 vlvinfop->ldvlv_context);
130 if( tag == LBER_ERROR ) goto exit;
133 tag = ber_printf(ber, /*{*/ "N}");
134 if( tag == LBER_ERROR ) goto exit;
136 ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
140 return(ld->ld_errno);
144 ld->ld_errno = LDAP_ENCODING_ERROR;
145 return(ld->ld_errno);
150 ldap_parse_vlv_control
152 Decode the Virtual List View control return information.
154 ld (IN) An LDAP session handle.
156 ctrls (IN) The address of a NULL-terminated array of
157 LDAPControl structures, typically obtained
158 by a call to ldap_parse_result().
160 target_posp (OUT) This result parameter is filled in with the list
161 index of the target entry. If this parameter is
162 NULL, the target position is not returned.
164 list_countp (OUT) This result parameter is filled in with the server's
165 estimate of the size of the list. If this parameter
166 is NULL, the size is not returned.
168 contextp (OUT) This result parameter is filled in with the address
169 of a struct berval that contains the server-
170 generated context identifier if one was returned by
171 the server. If the server did not return a context
172 identifier, this parameter will be set to NULL, even
174 The returned context SHOULD be used in the next call
175 to create a VLV sort control. The struct berval
176 returned SHOULD be disposed of by calling ber_bvfree()
177 when it is no longer needed. If NULL is passed for
178 contextp, the context identifier is not returned.
180 errcodep (OUT) This result parameter is filled in with the VLV
181 result code. If this parameter is NULL, the result
182 code is not returned.
187 VirtualListViewResponse ::= SEQUENCE {
188 targetPosition INTEGER (0 .. maxInt),
189 contentCount INTEGER (0 .. maxInt),
190 virtualListViewResult ENUMERATED {
193 unwillingToPerform (53),
194 insufficientAccessRights (50),
196 timeLimitExceeded (3),
197 adminLimitExceeded (11),
198 sortControlMissing (60),
199 offsetRangeError (61),
201 contextID OCTET STRING OPTIONAL }
206 ldap_parse_vlv_control(
209 unsigned long *target_posp,
210 unsigned long *list_countp,
211 struct berval **contextp,
215 LDAPControl *pControl;
217 unsigned long pos, count, err;
218 ber_tag_t tag, berTag;
221 assert( ld != NULL );
222 assert( LDAP_VALID( ld ) );
225 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
229 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
230 return(ld->ld_errno);
233 /* Search the list of control responses for a VLV control. */
234 for (i=0; ctrls[i]; i++) {
236 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
237 goto foundVLVControl;
240 /* No sort control was found. */
241 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
242 return(ld->ld_errno);
245 /* Create a BerElement from the berval returned in the control. */
246 ber = ber_init(&pControl->ldctl_value);
249 ld->ld_errno = LDAP_NO_MEMORY;
250 return(ld->ld_errno);
253 /* Extract the data returned in the control. */
254 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
256 if( tag == LBER_ERROR) {
258 ld->ld_errno = LDAP_DECODING_ERROR;
259 return(ld->ld_errno);
263 /* Since the context is the last item encoded, if caller doesn't want
264 it returned, don't decode it. */
266 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
267 tag = ber_scanf(ber, "tO", &berTag, contextp);
269 if( tag == LBER_ERROR) {
271 ld->ld_errno = LDAP_DECODING_ERROR;
272 return(ld->ld_errno);
279 /* Return data to the caller for items that were requested. */
284 *list_countp = count;
290 ld->ld_errno = LDAP_SUCCESS;
291 return(ld->ld_errno);