2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2006 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_vlvresponse_control
152 Decode the Virtual List View control return information.
154 ld (IN) An LDAP session handle.
156 ctrl (IN) The address of the LDAPControl structure.
158 target_posp (OUT) This result parameter is filled in with the list
159 index of the target entry. If this parameter is
160 NULL, the target position is not returned.
162 list_countp (OUT) This result parameter is filled in with the server's
163 estimate of the size of the list. If this parameter
164 is NULL, the size is not returned.
166 contextp (OUT) This result parameter is filled in with the address
167 of a struct berval that contains the server-
168 generated context identifier if one was returned by
169 the server. If the server did not return a context
170 identifier, this parameter will be set to NULL, even
172 The returned context SHOULD be used in the next call
173 to create a VLV sort control. The struct berval
174 returned SHOULD be disposed of by calling ber_bvfree()
175 when it is no longer needed. If NULL is passed for
176 contextp, the context identifier is not returned.
178 errcodep (OUT) This result parameter is filled in with the VLV
179 result code. If this parameter is NULL, the result
180 code is not returned.
185 VirtualListViewResponse ::= SEQUENCE {
186 targetPosition INTEGER (0 .. maxInt),
187 contentCount INTEGER (0 .. maxInt),
188 virtualListViewResult ENUMERATED {
191 unwillingToPerform (53),
192 insufficientAccessRights (50),
194 timeLimitExceeded (3),
195 adminLimitExceeded (11),
196 sortControlMissing (60),
197 offsetRangeError (61),
199 contextID OCTET STRING OPTIONAL }
204 ldap_parse_vlvresponse_control(
207 unsigned long *target_posp,
208 unsigned long *list_countp,
209 struct berval **contextp,
213 LDAPControl *pControl;
215 unsigned long pos, count, err;
216 ber_tag_t tag, berTag;
219 assert( ld != NULL );
220 assert( LDAP_VALID( ld ) );
223 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
227 ld->ld_errno = LDAP_PARAM_ERROR;
228 return(ld->ld_errno);
231 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
232 /* Not VLV Response control */
233 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
234 return(ld->ld_errno);
237 /* Create a BerElement from the berval returned in the control. */
238 ber = ber_init(&ctrl->ldctl_value);
241 ld->ld_errno = LDAP_NO_MEMORY;
242 return(ld->ld_errno);
245 /* Extract the data returned in the control. */
246 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
248 if( tag == LBER_ERROR) {
250 ld->ld_errno = LDAP_DECODING_ERROR;
251 return(ld->ld_errno);
255 /* Since the context is the last item encoded, if caller doesn't want
256 it returned, don't decode it. */
258 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
259 tag = ber_scanf(ber, "tO", &berTag, contextp);
261 if( tag == LBER_ERROR) {
263 ld->ld_errno = LDAP_DECODING_ERROR;
264 return(ld->ld_errno);
271 /* Return data to the caller for items that were requested. */
276 *list_countp = count;
282 ld->ld_errno = LDAP_SUCCESS;
283 return(ld->ld_errno);