]> git.sur5r.net Git - openldap/blob - libraries/libldap/pagectrl.c
Corrected memory allocation for cookie (ITS#5315)
[openldap] / libraries / libldap / pagectrl.c
1 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
2  *
3  * Copyright 1998-2008 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
143         if ( ctrlp == NULL ) {
144                 ld->ld_errno = LDAP_PARAM_ERROR;
145                 return ld->ld_errno;
146         }
147
148         ld->ld_errno = ldap_create_page_control_value( ld,
149                 pagesize, cookie, &value );
150         if ( ld->ld_errno == LDAP_SUCCESS ) {
151                 ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
152                         iscritical, &value, 0, ctrlp );
153                 if ( ld->ld_errno != LDAP_SUCCESS ) {
154                         LDAP_FREE( value.bv_val );
155                 }
156         }
157
158         return ld->ld_errno;
159 }
160
161
162 /* ---------------------------------------------------------------------------
163     ldap_parse_pageresponse_control
164
165     Decode a page control.
166
167     ld          (IN) An LDAP session handle
168     ctrl        (IN) The page response control
169     count      (OUT) The number of entries in the page.
170     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
171                      free the bv_val member of this structure.
172
173    ---------------------------------------------------------------------------*/
174
175 int
176 ldap_parse_pageresponse_control(
177         LDAP *ld,
178         LDAPControl *ctrl,
179         ber_int_t *countp,
180         struct berval *cookie )
181 {
182         BerElement *ber;
183         ber_tag_t tag;
184         ber_int_t count;
185
186         if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
187                 if ( ld )
188                         ld->ld_errno = LDAP_PARAM_ERROR;
189                 return LDAP_PARAM_ERROR;
190         }
191
192         /* Create a BerElement from the berval returned in the control. */
193         ber = ber_init( &ctrl->ldctl_value );
194
195         if ( ber == NULL ) {
196                 ld->ld_errno = LDAP_NO_MEMORY;
197                 return ld->ld_errno;
198         }
199
200         /* Extract the count and cookie from the control. */
201         tag = ber_scanf( ber, "{io}", &count, cookie );
202         ber_free( ber, 1 );
203
204         if ( tag == LBER_ERROR ) {
205                 ld->ld_errno = LDAP_DECODING_ERROR;
206         } else {
207                 ld->ld_errno = LDAP_SUCCESS;
208
209                 if ( countp != NULL ) {
210                         *countp = (unsigned long)count;
211                 }
212         }
213
214         return ld->ld_errno;
215 }
216
217 /* ---------------------------------------------------------------------------
218     ldap_parse_page_control
219
220     Decode a page control.
221
222     ld          (IN) An LDAP session handle
223     ctrls       (IN) Response controls
224     count      (OUT) The number of entries in the page.
225     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
226                      free the bv_val member of this structure.
227
228    ---------------------------------------------------------------------------*/
229
230 int
231 ldap_parse_page_control(
232         LDAP            *ld,
233         LDAPControl     **ctrls,
234         ber_int_t *countp,
235         struct berval   **cookiep )
236 {
237         LDAPControl *c;
238         struct berval   cookie;
239
240         if ( cookiep == NULL ) {
241                 ld->ld_errno = LDAP_PARAM_ERROR;
242                 return ld->ld_errno;
243         }
244
245         if ( ctrls == NULL ) {
246                 ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
247                 return ld->ld_errno;
248         }
249
250         c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
251         if ( c == NULL ) {
252                 /* No page control was found. */
253                 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
254                 return ld->ld_errno;
255         }
256
257         ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );
258         if ( ld->ld_errno == LDAP_SUCCESS ) {
259                 *cookiep = LDAP_MALLOC( sizeof( struct berval ) );
260                 if ( *cookiep == NULL ) {
261                         ld->ld_errno = LDAP_NO_MEMORY;
262                 } else {
263                         **cookiep = cookie;
264                 }
265         }
266
267         return ld->ld_errno;
268 }
269