]> git.sur5r.net Git - openldap/blob - libraries/libldap/pagectrl.c
happy new year
[openldap] / libraries / libldap / pagectrl.c
1 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
2  *
3  * Copyright 1998-2007 The OpenLDAP Foundation.
4  * Copyright 2006 Hans Leidekker
5  * All rights reserved.
6  *
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.
10  *
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>.
14  */
15
16 #include "portable.h"
17
18 #include <stdio.h>
19 #include <ac/stdlib.h>
20 #include <ac/string.h>
21 #include <ac/time.h>
22
23 #include "ldap-int.h"
24
25 /* ---------------------------------------------------------------------------
26     ldap_create_page_control_value
27
28     Create and encode the value of the paged results control (RFC 2696).
29
30     ld          (IN) An LDAP session handle
31     pagesize    (IN) Page size requested
32     cookie      (IN) Opaque structure used by the server to track its
33                      location in the search results.  NULL on the
34                      first call.
35     value      (OUT) Control value, SHOULD be freed by calling
36                                          ldap_memfree() when done.
37  
38     pagedResultsControl ::= SEQUENCE {
39             controlType     1.2.840.113556.1.4.319,
40             criticality     BOOLEAN DEFAULT FALSE,
41             controlValue    searchControlValue }
42
43     searchControlValue ::= SEQUENCE {
44             size            INTEGER (0..maxInt),
45                                     -- requested page size from client
46                                     -- result set size estimate from server
47             cookie          OCTET STRING }
48
49    ---------------------------------------------------------------------------*/
50
51 int
52 ldap_create_page_control_value(
53         LDAP *ld,
54         ber_int_t pagesize,
55         struct berval   *cookie,
56         struct berval   *value )
57 {
58         BerElement      *ber = NULL;
59         ber_tag_t       tag;
60         struct berval   null_cookie = { 0, NULL };
61
62         if ( ld == NULL || value == NULL ||
63                 pagesize < 1 || pagesize > LDAP_MAXINT )
64         {
65                 if ( ld )
66                         ld->ld_errno = LDAP_PARAM_ERROR;
67                 return LDAP_PARAM_ERROR;
68         }
69
70         assert( LDAP_VALID( ld ) );
71
72         value->bv_val = NULL;
73         value->bv_len = 0;
74
75         if ( cookie == NULL ) {
76                 cookie = &null_cookie;
77         }
78
79         ber = ldap_alloc_ber_with_options( ld );
80         if ( ber == NULL ) {
81                 ld->ld_errno = LDAP_NO_MEMORY;
82                 return ld->ld_errno;
83         }
84
85         tag = ber_printf( ber, "{iO}", pagesize, cookie );
86         if ( tag == LBER_ERROR ) {
87                 ld->ld_errno = LDAP_ENCODING_ERROR;
88                 goto done;
89         }
90
91         if ( ber_flatten2( ber, value, 1 ) == -1 ) {
92                 ld->ld_errno = LDAP_NO_MEMORY;
93         }
94
95 done:;
96         if ( ber != NULL ) {
97                 ber_free( ber, 1 );
98         }
99
100         return ld->ld_errno;
101 }
102
103
104 /* ---------------------------------------------------------------------------
105     ldap_create_page_control
106
107     Create and encode a page control.
108
109     ld          (IN) An LDAP session handle
110     pagesize    (IN) Page size requested
111     cookie      (IN) Opaque structure used by the server to track its
112                      location in the search results.  NULL on the
113                      first call.
114     value      (OUT) Control value, SHOULD be freed by calling
115                                          ldap_memfree() when done.
116     iscritical  (IN) Criticality
117     ctrlp      (OUT) LDAP control, SHOULD be freed by calling
118                                          ldap_control_free() when done.
119  
120     pagedResultsControl ::= SEQUENCE {
121             controlType     1.2.840.113556.1.4.319,
122             criticality     BOOLEAN DEFAULT FALSE,
123             controlValue    searchControlValue }
124
125     searchControlValue ::= SEQUENCE {
126             size            INTEGER (0..maxInt),
127                                     -- requested page size from client
128                                     -- result set size estimate from server
129             cookie          OCTET STRING }
130
131    ---------------------------------------------------------------------------*/
132
133 int
134 ldap_create_page_control(
135         LDAP            *ld,
136         ber_int_t       pagesize,
137         struct berval   *cookie,
138         int             iscritical,
139         LDAPControl     **ctrlp )
140 {
141         struct berval   value;
142         BerElement      *ber;
143
144         if ( ctrlp == NULL ) {
145                 ld->ld_errno = LDAP_PARAM_ERROR;
146                 return ld->ld_errno;
147         }
148
149         ld->ld_errno = ldap_create_page_control_value( ld,
150                 pagesize, cookie, &value );
151         if ( ld->ld_errno == LDAP_SUCCESS ) {
152                 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
153                         ld->ld_errno = LDAP_NO_MEMORY;
154                         return LDAP_NO_MEMORY;
155                 }
156
157                 ld->ld_errno = ldap_create_control( LDAP_CONTROL_PAGEDRESULTS,
158                         ber, iscritical, ctrlp );
159                 if ( ld->ld_errno == LDAP_SUCCESS ) {
160                         (*ctrlp)->ldctl_value = value;
161                 } else {
162                         LDAP_FREE( value.bv_val );
163                 }
164                 ber_free(ber, 1);
165         }
166
167         return ld->ld_errno;
168 }
169
170
171 /* ---------------------------------------------------------------------------
172     ldap_parse_pageresponse_control
173
174     Decode a page control.
175
176     ld          (IN) An LDAP session handle
177     ctrl        (IN) The page response control
178     count      (OUT) The number of entries in the page.
179     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
180                      free the bv_val member of this structure.
181
182    ---------------------------------------------------------------------------*/
183
184 int
185 ldap_parse_pageresponse_control(
186         LDAP *ld,
187         LDAPControl *ctrl,
188         ber_int_t *countp,
189         struct berval *cookie )
190 {
191         BerElement *ber;
192         ber_tag_t tag;
193         ber_int_t count;
194
195         if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
196                 if ( ld )
197                         ld->ld_errno = LDAP_PARAM_ERROR;
198                 return LDAP_PARAM_ERROR;
199         }
200
201         /* Create a BerElement from the berval returned in the control. */
202         ber = ber_init( &ctrl->ldctl_value );
203
204         if ( ber == NULL ) {
205                 ld->ld_errno = LDAP_NO_MEMORY;
206                 return ld->ld_errno;
207         }
208
209         /* Extract the count and cookie from the control. */
210         tag = ber_scanf( ber, "{io}", &count, cookie );
211         ber_free( ber, 1 );
212
213         if ( tag == LBER_ERROR ) {
214                 ld->ld_errno = LDAP_DECODING_ERROR;
215         } else {
216                 ld->ld_errno = LDAP_SUCCESS;
217
218                 if ( countp != NULL ) {
219                         *countp = (unsigned long)count;
220                 }
221         }
222
223         return ld->ld_errno;
224 }
225
226 /* ---------------------------------------------------------------------------
227     ldap_parse_page_control
228
229     Decode a page control.
230
231     ld          (IN) An LDAP session handle
232     ctrls       (IN) Response controls
233     count      (OUT) The number of entries in the page.
234     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
235                      free the bv_val member of this structure.
236
237    ---------------------------------------------------------------------------*/
238
239 int
240 ldap_parse_page_control(
241         LDAP            *ld,
242         LDAPControl     **ctrls,
243         ber_int_t *countp,
244         struct berval   **cookiep )
245 {
246         LDAPControl *c;
247         struct berval   cookie;
248
249         if ( cookiep == NULL ) {
250                 ld->ld_errno = LDAP_PARAM_ERROR;
251                 return ld->ld_errno;
252         }
253
254         if ( ctrls == NULL ) {
255                 ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
256                 return ld->ld_errno;
257         }
258
259         c = ldap_find_control( LDAP_CONTROL_PAGEDRESULTS, ctrls );
260         if ( c == NULL ) {
261                 /* No page control was found. */
262                 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
263                 return ld->ld_errno;
264         }
265
266         ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );
267         if ( ld->ld_errno == LDAP_SUCCESS ) {
268                 *cookiep = LDAP_MALLOC( sizeof( struct berval * ) );
269                 if ( *cookiep == NULL ) {
270                         ld->ld_errno = LDAP_NO_MEMORY;
271                 } else {
272                         **cookiep = cookie;
273                 }
274         }
275
276         return ld->ld_errno;
277 }
278