No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / openldap / dist / libraries / libldap / vlvctrl.c
blobb298f2058c45bcaa66d0fd5d9707d7c08da4badc
1 /* $OpenLDAP: pkg/ldap/libraries/libldap/vlvctrl.c,v 1.21.2.3 2008/02/11 23:26:41 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2008 The OpenLDAP Foundation.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
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.
25 *---
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.
31 #include "portable.h"
33 #include <stdio.h>
34 #include <ac/stdlib.h>
35 #include <ac/string.h>
36 #include <ac/time.h>
38 #include "ldap-int.h"
40 #define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
41 #define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
42 #define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
45 /*---
46 ldap_create_vlv_control
48 Create and encode the Virtual List View control.
50 ld (IN) An LDAP session handle.
52 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
53 are used to construct the value of the control
54 that is created.
56 value (OUT) A struct berval that contains the value to be assigned to the ldctl_value member
57 of an LDAPControl structure that contains the
58 VirtualListViewRequest control.
59 The bv_val member of the berval structure
60 SHOULD be freed when it is no longer in use by
61 calling ldap_memfree().
64 Ber encoding
66 VirtualListViewRequest ::= SEQUENCE {
67 beforeCount INTEGER (0 .. maxInt),
68 afterCount INTEGER (0 .. maxInt),
69 CHOICE {
70 byoffset [0] SEQUENCE, {
71 offset INTEGER (0 .. maxInt),
72 contentCount INTEGER (0 .. maxInt) }
73 [1] greaterThanOrEqual assertionValue }
74 contextID OCTET STRING OPTIONAL }
77 Note: The first time the VLV control is created, the ldvlv_context
78 field of the LDAPVLVInfo structure should be set to NULL.
79 The context obtained from calling ldap_parse_vlv_control()
80 should be used as the context in the next ldap_create_vlv_control
81 call.
83 ---*/
85 int
86 ldap_create_vlv_control_value(
87 LDAP *ld,
88 LDAPVLVInfo *vlvinfop,
89 struct berval *value )
91 ber_tag_t tag;
92 BerElement *ber;
94 if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
95 if ( ld )
96 ld->ld_errno = LDAP_PARAM_ERROR;
97 return LDAP_PARAM_ERROR;
100 assert( LDAP_VALID( ld ) );
102 value->bv_val = NULL;
103 value->bv_len = 0;
105 ber = ldap_alloc_ber_with_options( ld );
106 if ( ber == NULL ) {
107 ld->ld_errno = LDAP_NO_MEMORY;
108 return ld->ld_errno;
111 tag = ber_printf( ber, "{ii" /*}*/,
112 vlvinfop->ldvlv_before_count,
113 vlvinfop->ldvlv_after_count );
114 if ( tag == LBER_ERROR ) {
115 goto error_return;
118 if ( vlvinfop->ldvlv_attrvalue == NULL ) {
119 tag = ber_printf( ber, "t{iiN}",
120 LDAP_VLVBYINDEX_IDENTIFIER,
121 vlvinfop->ldvlv_offset,
122 vlvinfop->ldvlv_count );
123 if ( tag == LBER_ERROR ) {
124 goto error_return;
127 } else {
128 tag = ber_printf( ber, "tO",
129 LDAP_VLVBYVALUE_IDENTIFIER,
130 vlvinfop->ldvlv_attrvalue );
131 if ( tag == LBER_ERROR ) {
132 goto error_return;
136 if ( vlvinfop->ldvlv_context ) {
137 tag = ber_printf( ber, "tO",
138 LDAP_VLVCONTEXT_IDENTIFIER,
139 vlvinfop->ldvlv_context );
140 if ( tag == LBER_ERROR ) {
141 goto error_return;
145 tag = ber_printf( ber, /*{*/ "N}" );
146 if ( tag == LBER_ERROR ) {
147 goto error_return;
150 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
151 ld->ld_errno = LDAP_NO_MEMORY;
154 if ( 0 ) {
155 error_return:;
156 ld->ld_errno = LDAP_ENCODING_ERROR;
159 if ( ber != NULL ) {
160 ber_free( ber, 1 );
163 return ld->ld_errno;
166 /*---
167 ldap_create_vlv_control
169 Create and encode the Virtual List View control.
171 ld (IN) An LDAP session handle.
173 vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
174 are used to construct the value of the control
175 that is created.
177 ctrlp (OUT) A result parameter that will be assigned the address
178 of an LDAPControl structure that contains the
179 VirtualListViewRequest control created by this function.
180 The memory occupied by the LDAPControl structure
181 SHOULD be freed when it is no longer in use by
182 calling ldap_control_free().
185 Ber encoding
187 VirtualListViewRequest ::= SEQUENCE {
188 beforeCount INTEGER (0 .. maxInt),
189 afterCount INTEGER (0 .. maxInt),
190 CHOICE {
191 byoffset [0] SEQUENCE, {
192 offset INTEGER (0 .. maxInt),
193 contentCount INTEGER (0 .. maxInt) }
194 [1] greaterThanOrEqual assertionValue }
195 contextID OCTET STRING OPTIONAL }
198 Note: The first time the VLV control is created, the ldvlv_context
199 field of the LDAPVLVInfo structure should be set to NULL.
200 The context obtained from calling ldap_parse_vlv_control()
201 should be used as the context in the next ldap_create_vlv_control
202 call.
204 ---*/
207 ldap_create_vlv_control(
208 LDAP *ld,
209 LDAPVLVInfo *vlvinfop,
210 LDAPControl **ctrlp )
212 struct berval value;
214 if ( ctrlp == NULL ) {
215 ld->ld_errno = LDAP_PARAM_ERROR;
216 return ld->ld_errno;
219 ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
220 if ( ld->ld_errno == LDAP_SUCCESS ) {
222 ld->ld_errno = ldap_control_create( LDAP_CONTROL_VLVREQUEST,
223 1, &value, 0, ctrlp );
224 if ( ld->ld_errno != LDAP_SUCCESS ) {
225 LDAP_FREE( value.bv_val );
229 return ld->ld_errno;
233 /*---
234 ldap_parse_vlvresponse_control
236 Decode the Virtual List View control return information.
238 ld (IN) An LDAP session handle.
240 ctrl (IN) The address of the LDAPControl structure.
242 target_posp (OUT) This result parameter is filled in with the list
243 index of the target entry. If this parameter is
244 NULL, the target position is not returned.
246 list_countp (OUT) This result parameter is filled in with the server's
247 estimate of the size of the list. If this parameter
248 is NULL, the size is not returned.
250 contextp (OUT) This result parameter is filled in with the address
251 of a struct berval that contains the server-
252 generated context identifier if one was returned by
253 the server. If the server did not return a context
254 identifier, this parameter will be set to NULL, even
255 if an error occured.
256 The returned context SHOULD be used in the next call
257 to create a VLV sort control. The struct berval
258 returned SHOULD be disposed of by calling ber_bvfree()
259 when it is no longer needed. If NULL is passed for
260 contextp, the context identifier is not returned.
262 errcodep (OUT) This result parameter is filled in with the VLV
263 result code. If this parameter is NULL, the result
264 code is not returned.
267 Ber encoding
269 VirtualListViewResponse ::= SEQUENCE {
270 targetPosition INTEGER (0 .. maxInt),
271 contentCount INTEGER (0 .. maxInt),
272 virtualListViewResult ENUMERATED {
273 success (0),
274 operatonsError (1),
275 unwillingToPerform (53),
276 insufficientAccessRights (50),
277 busy (51),
278 timeLimitExceeded (3),
279 adminLimitExceeded (11),
280 sortControlMissing (60),
281 offsetRangeError (61),
282 other (80) },
283 contextID OCTET STRING OPTIONAL }
285 ---*/
288 ldap_parse_vlvresponse_control(
289 LDAP *ld,
290 LDAPControl *ctrl,
291 ber_int_t *target_posp,
292 ber_int_t *list_countp,
293 struct berval **contextp,
294 ber_int_t *errcodep )
296 BerElement *ber;
297 ber_int_t pos, count, err;
298 ber_tag_t tag, berTag;
299 ber_len_t berLen;
301 assert( ld != NULL );
302 assert( LDAP_VALID( ld ) );
304 if (contextp) {
305 *contextp = NULL; /* Make sure we return a NULL if error occurs. */
308 if (ctrl == NULL) {
309 ld->ld_errno = LDAP_PARAM_ERROR;
310 return(ld->ld_errno);
313 if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
314 /* Not VLV Response control */
315 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
316 return(ld->ld_errno);
319 /* Create a BerElement from the berval returned in the control. */
320 ber = ber_init(&ctrl->ldctl_value);
322 if (ber == NULL) {
323 ld->ld_errno = LDAP_NO_MEMORY;
324 return(ld->ld_errno);
327 /* Extract the data returned in the control. */
328 tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
330 if( tag == LBER_ERROR) {
331 ber_free(ber, 1);
332 ld->ld_errno = LDAP_DECODING_ERROR;
333 return(ld->ld_errno);
337 /* Since the context is the last item encoded, if caller doesn't want
338 it returned, don't decode it. */
339 if (contextp) {
340 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
341 tag = ber_scanf(ber, "tO", &berTag, contextp);
343 if( tag == LBER_ERROR) {
344 ber_free(ber, 1);
345 ld->ld_errno = LDAP_DECODING_ERROR;
346 return(ld->ld_errno);
351 ber_free(ber, 1);
353 /* Return data to the caller for items that were requested. */
354 if (target_posp) *target_posp = pos;
355 if (list_countp) *list_countp = count;
356 if (errcodep) *errcodep = err;
358 ld->ld_errno = LDAP_SUCCESS;
359 return(ld->ld_errno);