2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2016 The OpenLDAP Foundation.
5 * Copyright 2006 Hans Leidekker
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
20 #include <ac/stdlib.h>
21 #include <ac/string.h>
26 /* ---------------------------------------------------------------------------
27 ldap_create_page_control_value
29 Create and encode the value of the paged results control (RFC 2696).
31 ld (IN) An LDAP session handle
32 pagesize (IN) Page size requested
33 cookie (IN) Opaque structure used by the server to track its
34 location in the search results. NULL on the
36 value (OUT) Control value, SHOULD be freed by calling
37 ldap_memfree() when done.
39 pagedResultsControl ::= SEQUENCE {
40 controlType 1.2.840.113556.1.4.319,
41 criticality BOOLEAN DEFAULT FALSE,
42 controlValue searchControlValue }
44 searchControlValue ::= SEQUENCE {
45 size INTEGER (0..maxInt),
46 -- requested page size from client
47 -- result set size estimate from server
50 ---------------------------------------------------------------------------*/
53 ldap_create_page_control_value(
56 struct berval *cookie,
57 struct berval *value )
59 BerElement *ber = NULL;
61 struct berval null_cookie = { 0, NULL };
63 if ( ld == NULL || value == NULL ||
64 pagesize < 1 || pagesize > LDAP_MAXINT )
67 ld->ld_errno = LDAP_PARAM_ERROR;
68 return LDAP_PARAM_ERROR;
71 assert( LDAP_VALID( ld ) );
75 ld->ld_errno = LDAP_SUCCESS;
77 if ( cookie == NULL ) {
78 cookie = &null_cookie;
81 ber = ldap_alloc_ber_with_options( ld );
83 ld->ld_errno = LDAP_NO_MEMORY;
87 tag = ber_printf( ber, "{iO}", pagesize, cookie );
88 if ( tag == LBER_ERROR ) {
89 ld->ld_errno = LDAP_ENCODING_ERROR;
93 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
94 ld->ld_errno = LDAP_NO_MEMORY;
106 /* ---------------------------------------------------------------------------
107 ldap_create_page_control
109 Create and encode a page control.
111 ld (IN) An LDAP session handle
112 pagesize (IN) Page size requested
113 cookie (IN) Opaque structure used by the server to track its
114 location in the search results. NULL on the
116 value (OUT) Control value, SHOULD be freed by calling
117 ldap_memfree() when done.
118 iscritical (IN) Criticality
119 ctrlp (OUT) LDAP control, SHOULD be freed by calling
120 ldap_control_free() when done.
122 pagedResultsControl ::= SEQUENCE {
123 controlType 1.2.840.113556.1.4.319,
124 criticality BOOLEAN DEFAULT FALSE,
125 controlValue searchControlValue }
127 searchControlValue ::= SEQUENCE {
128 size INTEGER (0..maxInt),
129 -- requested page size from client
130 -- result set size estimate from server
131 cookie OCTET STRING }
133 ---------------------------------------------------------------------------*/
136 ldap_create_page_control(
139 struct berval *cookie,
141 LDAPControl **ctrlp )
145 if ( ctrlp == NULL ) {
146 ld->ld_errno = LDAP_PARAM_ERROR;
150 ld->ld_errno = ldap_create_page_control_value( ld,
151 pagesize, cookie, &value );
152 if ( ld->ld_errno == LDAP_SUCCESS ) {
153 ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
154 iscritical, &value, 0, ctrlp );
155 if ( ld->ld_errno != LDAP_SUCCESS ) {
156 LDAP_FREE( value.bv_val );
164 /* ---------------------------------------------------------------------------
165 ldap_parse_pageresponse_control
167 Decode a page control.
169 ld (IN) An LDAP session handle
170 ctrl (IN) The page response control
171 count (OUT) The number of entries in the page.
172 cookie (OUT) Opaque cookie. Use ldap_memfree() to
173 free the bv_val member of this structure.
175 ---------------------------------------------------------------------------*/
178 ldap_parse_pageresponse_control(
182 struct berval *cookie )
188 if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
190 ld->ld_errno = LDAP_PARAM_ERROR;
191 return LDAP_PARAM_ERROR;
194 /* Create a BerElement from the berval returned in the control. */
195 ber = ber_init( &ctrl->ldctl_value );
198 ld->ld_errno = LDAP_NO_MEMORY;
202 /* Extract the count and cookie from the control. */
203 tag = ber_scanf( ber, "{io}", &count, cookie );
206 if ( tag == LBER_ERROR ) {
207 ld->ld_errno = LDAP_DECODING_ERROR;
209 ld->ld_errno = LDAP_SUCCESS;
211 if ( countp != NULL ) {
212 *countp = (unsigned long)count;
219 /* ---------------------------------------------------------------------------
220 ldap_parse_page_control
222 Decode a page control.
224 ld (IN) An LDAP session handle
225 ctrls (IN) Response controls
226 count (OUT) The number of entries in the page.
227 cookie (OUT) Opaque cookie. Use ldap_memfree() to
228 free the bv_val member of this structure.
230 ---------------------------------------------------------------------------*/
233 ldap_parse_page_control(
237 struct berval **cookiep )
240 struct berval cookie;
242 if ( cookiep == NULL ) {
243 ld->ld_errno = LDAP_PARAM_ERROR;
247 if ( ctrls == NULL ) {
248 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
252 c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
254 /* No page control was found. */
255 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
259 ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );
260 if ( ld->ld_errno == LDAP_SUCCESS ) {
261 *cookiep = LDAP_MALLOC( sizeof( struct berval ) );
262 if ( *cookiep == NULL ) {
263 ld->ld_errno = LDAP_NO_MEMORY;