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