/* $OpenLDAP$ */1/* This work is part of OpenLDAP Software <http://www.openldap.org/>.2*3* Copyright 1998-2024 The OpenLDAP Foundation.4* Copyright 2006 Hans Leidekker5* All rights reserved.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted only as authorized by the OpenLDAP9* Public License.10*11* A copy of this license is available in the file LICENSE in the12* top-level directory of the distribution or, alternatively, at13* <http://www.OpenLDAP.org/license.html>.14*/1516#include "portable.h"1718#include <stdio.h>19#include <ac/stdlib.h>20#include <ac/string.h>21#include <ac/time.h>2223#include "ldap-int.h"2425/* ---------------------------------------------------------------------------26ldap_create_page_control_value2728Create and encode the value of the paged results control (RFC 2696).2930ld (IN) An LDAP session handle31pagesize (IN) Page size requested32cookie (IN) Opaque structure used by the server to track its33location in the search results. NULL on the34first call.35value (OUT) Control value, SHOULD be freed by calling36ldap_memfree() when done.3738pagedResultsControl ::= SEQUENCE {39controlType 1.2.840.113556.1.4.319,40criticality BOOLEAN DEFAULT FALSE,41controlValue searchControlValue }4243searchControlValue ::= SEQUENCE {44size INTEGER (0..maxInt),45-- requested page size from client46-- result set size estimate from server47cookie OCTET STRING }4849---------------------------------------------------------------------------*/5051int52ldap_create_page_control_value(53LDAP *ld,54ber_int_t pagesize,55struct berval *cookie,56struct berval *value )57{58BerElement *ber = NULL;59ber_tag_t tag;60struct berval null_cookie = { 0, NULL };6162if ( ld == NULL || value == NULL ||63pagesize < 1 || pagesize > LDAP_MAXINT )64{65if ( ld )66ld->ld_errno = LDAP_PARAM_ERROR;67return LDAP_PARAM_ERROR;68}6970assert( LDAP_VALID( ld ) );7172value->bv_val = NULL;73value->bv_len = 0;74ld->ld_errno = LDAP_SUCCESS;7576if ( cookie == NULL ) {77cookie = &null_cookie;78}7980ber = ldap_alloc_ber_with_options( ld );81if ( ber == NULL ) {82ld->ld_errno = LDAP_NO_MEMORY;83return ld->ld_errno;84}8586tag = ber_printf( ber, "{iO}", pagesize, cookie );87if ( tag == LBER_ERROR ) {88ld->ld_errno = LDAP_ENCODING_ERROR;89goto done;90}9192if ( ber_flatten2( ber, value, 1 ) == -1 ) {93ld->ld_errno = LDAP_NO_MEMORY;94}9596done:;97if ( ber != NULL ) {98ber_free( ber, 1 );99}100101return ld->ld_errno;102}103104105/* ---------------------------------------------------------------------------106ldap_create_page_control107108Create and encode a page control.109110ld (IN) An LDAP session handle111pagesize (IN) Page size requested112cookie (IN) Opaque structure used by the server to track its113location in the search results. NULL on the114first call.115value (OUT) Control value, SHOULD be freed by calling116ldap_memfree() when done.117iscritical (IN) Criticality118ctrlp (OUT) LDAP control, SHOULD be freed by calling119ldap_control_free() when done.120121pagedResultsControl ::= SEQUENCE {122controlType 1.2.840.113556.1.4.319,123criticality BOOLEAN DEFAULT FALSE,124controlValue searchControlValue }125126searchControlValue ::= SEQUENCE {127size INTEGER (0..maxInt),128-- requested page size from client129-- result set size estimate from server130cookie OCTET STRING }131132---------------------------------------------------------------------------*/133134int135ldap_create_page_control(136LDAP *ld,137ber_int_t pagesize,138struct berval *cookie,139int iscritical,140LDAPControl **ctrlp )141{142struct berval value;143144if ( ctrlp == NULL ) {145ld->ld_errno = LDAP_PARAM_ERROR;146return ld->ld_errno;147}148149ld->ld_errno = ldap_create_page_control_value( ld,150pagesize, cookie, &value );151if ( ld->ld_errno == LDAP_SUCCESS ) {152ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,153iscritical, &value, 0, ctrlp );154if ( ld->ld_errno != LDAP_SUCCESS ) {155LDAP_FREE( value.bv_val );156}157}158159return ld->ld_errno;160}161162163/* ---------------------------------------------------------------------------164ldap_parse_pageresponse_control165166Decode a page control.167168ld (IN) An LDAP session handle169ctrl (IN) The page response control170count (OUT) The number of entries in the page.171cookie (OUT) Opaque cookie. Use ldap_memfree() to172free the bv_val member of this structure.173174---------------------------------------------------------------------------*/175176int177ldap_parse_pageresponse_control(178LDAP *ld,179LDAPControl *ctrl,180ber_int_t *countp,181struct berval *cookie )182{183BerElement *ber;184ber_tag_t tag;185ber_int_t count;186187if ( ld == NULL || ctrl == NULL || cookie == NULL ) {188if ( ld )189ld->ld_errno = LDAP_PARAM_ERROR;190return LDAP_PARAM_ERROR;191}192193/* Create a BerElement from the berval returned in the control. */194ber = ber_init( &ctrl->ldctl_value );195196if ( ber == NULL ) {197ld->ld_errno = LDAP_NO_MEMORY;198return ld->ld_errno;199}200201/* Extract the count and cookie from the control. */202tag = ber_scanf( ber, "{io}", &count, cookie );203ber_free( ber, 1 );204205if ( tag == LBER_ERROR ) {206ld->ld_errno = LDAP_DECODING_ERROR;207} else {208ld->ld_errno = LDAP_SUCCESS;209210if ( countp != NULL ) {211*countp = (unsigned long)count;212}213}214215return ld->ld_errno;216}217218/* ---------------------------------------------------------------------------219ldap_parse_page_control220221Decode a page control.222223ld (IN) An LDAP session handle224ctrls (IN) Response controls225count (OUT) The number of entries in the page.226cookie (OUT) Opaque cookie. Use ldap_memfree() to227free the bv_val member of this structure.228229---------------------------------------------------------------------------*/230231int232ldap_parse_page_control(233LDAP *ld,234LDAPControl **ctrls,235ber_int_t *countp,236struct berval **cookiep )237{238LDAPControl *c;239struct berval cookie;240241if ( cookiep == NULL ) {242ld->ld_errno = LDAP_PARAM_ERROR;243return ld->ld_errno;244}245246if ( ctrls == NULL ) {247ld->ld_errno = LDAP_CONTROL_NOT_FOUND;248return ld->ld_errno;249}250251c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );252if ( c == NULL ) {253/* No page control was found. */254ld->ld_errno = LDAP_CONTROL_NOT_FOUND;255return ld->ld_errno;256}257258ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );259if ( ld->ld_errno == LDAP_SUCCESS ) {260*cookiep = LDAP_MALLOC( sizeof( struct berval ) );261if ( *cookiep == NULL ) {262ld->ld_errno = LDAP_NO_MEMORY;263} else {264**cookiep = cookie;265}266}267268return ld->ld_errno;269}270271272