1 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 * Copyright 1998-2006 The OpenLDAP Foundation.
4 * Copyright 2006 Hans Leidekker
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 /* ---------------------------------------------------------------------------
44 ldap_create_page_control_value
46 Create and encode the value of the paged results control (RFC 2696).
48 ld (IN) An LDAP session handle, as obtained from a call to
51 pagesize (IN) The number of entries to return per page.
53 cookie (IN) Opaque structure used by the server to track its
54 location in the search results. Pass in NULL on the
57 value (OUT) the pointer to a struct berval; it is filled by this function
58 with the value that must be assigned to the ldctl_value member
59 of the LDAPControl structure. The bv_val member of the berval
60 structure SHOULD be freed by calling ldap_memfree() when done.
64 pagedResultsControl ::= SEQUENCE {
65 controlType 1.2.840.113556.1.4.319,
66 criticality BOOLEAN DEFAULT FALSE,
67 controlValue searchControlValue }
69 searchControlValue ::= SEQUENCE {
70 size INTEGER (0..maxInt),
71 -- requested page size from client
72 -- result set size estimate from server
75 ---------------------------------------------------------------------------*/
78 ldap_create_page_control_value(
80 unsigned long pagesize,
81 struct berval *cookie,
82 struct berval *value )
84 BerElement *ber = NULL;
86 struct berval null_cookie = { 0, NULL };
88 if ( ld == NULL || value == NULL ) {
89 ld->ld_errno = LDAP_PARAM_ERROR;
93 assert( LDAP_VALID( ld ) );
98 if ( cookie == NULL ) {
99 cookie = &null_cookie;
102 ber = ldap_alloc_ber_with_options( ld );
104 ld->ld_errno = LDAP_NO_MEMORY;
108 tag = ber_printf( ber, "{iO}", pagesize, cookie );
109 if ( tag == LBER_ERROR ) {
113 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
114 ld->ld_errno = LDAP_NO_MEMORY;
119 ld->ld_errno = LDAP_ENCODING_ERROR;
130 /* ---------------------------------------------------------------------------
131 ldap_create_page_control
133 Create and encode a page control.
135 ld (IN) An LDAP session handle, as obtained from a call to
138 pagesize (IN) The number of entries to return per page.
140 cookie (IN) Opaque structure used by the server to track its
141 location in the search results. Pass in NULL on the
144 iscritical (IN) 0 - The control is not critical to the operation.
145 non-zero - The control is critical to the operation.
147 ctrlp (OUT) Returns a pointer to the LDAPControl created. This
148 control SHOULD be freed by calling ldap_control_free()
153 pagedResultsControl ::= SEQUENCE {
154 controlType 1.2.840.113556.1.4.319,
155 criticality BOOLEAN DEFAULT FALSE,
156 controlValue searchControlValue }
158 searchControlValue ::= SEQUENCE {
159 size INTEGER (0..maxInt),
160 -- requested page size from client
161 -- result set size estimate from server
162 cookie OCTET STRING }
164 ---------------------------------------------------------------------------*/
167 ldap_create_page_control(
169 unsigned long pagesize,
170 struct berval *cookie,
172 LDAPControl **ctrlp )
176 if ( ctrlp == NULL ) {
177 ld->ld_errno = LDAP_PARAM_ERROR;
181 ld->ld_errno = ldap_create_page_control_value( ld, pagesize, cookie, &value );
182 if ( ld->ld_errno == LDAP_SUCCESS ) {
183 ld->ld_errno = ldap_create_control( LDAP_CONTROL_PAGEDRESULTS,
184 NULL, iscritical, ctrlp );
185 if ( ld->ld_errno == LDAP_SUCCESS ) {
186 (*ctrlp)->ldctl_value = value;
188 LDAP_FREE( value.bv_val );
196 /* ---------------------------------------------------------------------------
197 ldap_parse_pageresponse_control
199 Decode a page control.
201 ld (IN) An LDAP session handle, as obtained from a call to
204 ctrls (IN) The address of a NULL-terminated array of
205 LDAPControl structures, typically obtained by a
206 call to ldap_parse_result(). The array SHOULD include
209 count (OUT) The number of entries returned in the page.
211 cookie (OUT) Opaque structure used by the server to track its
212 location in the search results. Use ldap_memfree() to
213 free the bv_val member of this structure.
215 ---------------------------------------------------------------------------*/
218 ldap_parse_pageresponse_control(
221 unsigned long *countp,
222 struct berval *cookie )
228 if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
229 ld->ld_errno = LDAP_PARAM_ERROR;
233 /* Create a BerElement from the berval returned in the control. */
234 ber = ber_init( &ctrl->ldctl_value );
237 ld->ld_errno = LDAP_NO_MEMORY;
241 /* Extract the count and cookie from the control. */
242 tag = ber_scanf( ber, "{io}", &count, cookie );
245 if ( tag == LBER_ERROR ) {
246 ld->ld_errno = LDAP_DECODING_ERROR;
248 ld->ld_errno = LDAP_SUCCESS;
250 if ( countp != NULL ) {
251 *countp = (unsigned long)count;
258 /* ---------------------------------------------------------------------------
259 ldap_parse_page_control
261 Decode a page control.
263 ld (IN) An LDAP session handle, as obtained from a call to
266 ctrls (IN) The address of a NULL-terminated array of
267 LDAPControl structures, typically obtained by a
268 call to ldap_parse_result(). The array SHOULD include
271 count (OUT) The number of entries returned in the page.
273 cookie (OUT) Opaque structure used by the server to track its
274 location in the search results. Use ber_bvfree() to
277 ---------------------------------------------------------------------------*/
280 ldap_parse_page_control(
283 unsigned long *countp,
284 struct berval **cookiep )
286 struct berval cookie;
289 if ( cookiep == NULL ) {
290 ld->ld_errno = LDAP_PARAM_ERROR;
294 if ( ctrls == NULL ) {
295 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
299 /* Search the list of control responses for a page control. */
300 for ( i = 0; ctrls[i]; i++ ) {
301 if ( strcmp( LDAP_CONTROL_PAGEDRESULTS, ctrls[ i ]->ldctl_oid ) == 0 ) {
306 /* No page control was found. */
307 if ( ctrls[ i ] == NULL ) {
308 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
312 ld->ld_errno = ldap_parse_pageresponse_control( ld, ctrls[ i ], countp, &cookie );
313 if ( ld->ld_errno == LDAP_SUCCESS ) {
314 *cookiep = LDAP_MALLOC( sizeof( struct berval * ) );
315 if ( *cookiep == NULL ) {
316 ld->ld_errno = LDAP_NO_MEMORY;