From de79a7bfec60776ffd5a3968fa78c4a00bc05a55 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sun, 8 Jan 2006 22:03:30 +0000 Subject: [PATCH] rework API functions to create/parse controls; add client API functions to handle RFC2696 paged results (ITS#4314; patch from Hans Leidekker with changes) --- include/ldap.h | 51 ++++- libraries/libldap/Makefile.in | 4 +- libraries/libldap/pagectrl.c | 324 ++++++++++++++++++++++++++++++++ libraries/libldap/sortctrl.c | 163 +++++++++++----- libraries/libldap/vlvctrl.c | 163 ++++++++++++---- libraries/libldap_r/Makefile.in | 4 +- 6 files changed, 620 insertions(+), 89 deletions(-) create mode 100644 libraries/libldap/pagectrl.c diff --git a/include/ldap.h b/include/ldap.h index 24133f614f..ef83421257 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -1936,6 +1936,41 @@ ldap_turn_s LDAP_P(( LDAP *ld, LDAPControl **sctrl, LDAPControl **cctrl )); +/* + * LDAP Paged Results + * in pagectrl.c + */ +#define LDAP_API_FEATURE_PAGED_RESULTS 1000 + +LDAP_F( int ) +ldap_create_page_control_value LDAP_P(( + LDAP *ld, + unsigned long pagesize, + struct berval *cookie, + struct berval *value )); + +LDAP_F( int ) +ldap_create_page_control LDAP_P(( + LDAP *ld, + unsigned long pagesize, + struct berval *cookie, + int iscritical, + LDAPControl **ctrlp )); + +LDAP_F( int ) +ldap_parse_page_control LDAP_P(( + LDAP *ld, + LDAPControl **ctrls, + unsigned long *count, + struct berval **cookie )); + +LDAP_F( int ) +ldap_parse_pageresponse_control LDAP_P(( + LDAP *ld, + LDAPControl *ctrl, + unsigned long *count, + struct berval *cookie )); + /* * LDAP Server Side Sort * in sortctrl.c @@ -1958,6 +1993,12 @@ LDAP_F( void ) ldap_free_sort_keylist LDAP_P(( LDAPSortKey **sortkeylist )); +LDAP_F( int ) +ldap_create_sort_control_value LDAP_P(( + LDAP *ld, + LDAPSortKey **keyList, + struct berval *value )); + LDAP_F( int ) ldap_create_sort_control LDAP_P(( LDAP *ld, @@ -1966,9 +2007,9 @@ ldap_create_sort_control LDAP_P(( LDAPControl **ctrlp )); LDAP_F( int ) -ldap_parse_sortresult_control LDAP_P(( +ldap_parse_sortresponse_control LDAP_P(( LDAP *ld, - LDAPControl **ctrlp, + LDAPControl *ctrl, unsigned long *result, char **attribute )); @@ -1991,6 +2032,12 @@ typedef struct ldapvlvinfo { void * ldvlv_extradata; } LDAPVLVInfo; +LDAP_F( int ) +ldap_create_vlv_control_value LDAP_P(( + LDAP *ld, + LDAPVLVInfo *ldvlistp, + struct berval *value)); + LDAP_F( int ) ldap_create_vlv_control LDAP_P(( LDAP *ld, diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in index 3e5028cf5b..2cb20610ea 100644 --- a/libraries/libldap/Makefile.in +++ b/libraries/libldap/Makefile.in @@ -23,7 +23,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \ sasl.c sbind.c kbind.c unbind.c cancel.c \ filter.c free.c sort.c passwd.c whoami.c \ getdn.c getentry.c getattr.c getvalues.c addentry.c \ - request.c os-ip.c url.c sortctrl.c vlvctrl.c \ + request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \ init.c options.c print.c string.c util-int.c schema.c \ charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \ turn.c groupings.c txn.c ppolicy.c dds.c @@ -34,7 +34,7 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \ sasl.lo sbind.lo kbind.lo unbind.lo cancel.lo \ filter.lo free.lo sort.lo passwd.lo whoami.lo \ getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \ - request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \ + request.lo os-ip.lo url.lo pagectrl.o sortctrl.lo vlvctrl.lo \ init.lo options.lo print.lo string.lo util-int.lo schema.lo \ charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \ turn.lo groupings.lo txn.lo ppolicy.lo dds.lo diff --git a/libraries/libldap/pagectrl.c b/libraries/libldap/pagectrl.c new file mode 100644 index 0000000000..67f648c37b --- /dev/null +++ b/libraries/libldap/pagectrl.c @@ -0,0 +1,324 @@ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 2006 Hans Leidekker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved. + * + * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND + * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT + * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS + * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" + * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION + * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP + * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT + * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. + */ +/* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License + * can be found in the file "build/LICENSE-2.0.1" in this distribution + * of OpenLDAP Software. + */ +/* Portions Copyright (C) The Internet Society (1997) + * ASN.1 fragments are from RFC 2251; see RFC for full legal notices. + */ + +#include "portable.h" + +#include +#include +#include +#include + +#include "ldap-int.h" + +/* --------------------------------------------------------------------------- + ldap_create_page_control_value + + Create and encode the value of the paged results control (RFC 2696). + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + pagesize (IN) The number of entries to return per page. + + cookie (IN) Opaque structure used by the server to track its + location in the search results. Pass in NULL on the + first call. + + value (OUT) the pointer to a struct berval; it is filled by this function + with the value that must be assigned to the ldctl_value member + of the LDAPControl structure. The bv_val member of the berval + structure SHOULD be freed by calling ldap_memfree() when done. + + Ber encoding + + pagedResultsControl ::= SEQUENCE { + controlType 1.2.840.113556.1.4.319, + criticality BOOLEAN DEFAULT FALSE, + controlValue searchControlValue } + + searchControlValue ::= SEQUENCE { + size INTEGER (0..maxInt), + -- requested page size from client + -- result set size estimate from server + cookie OCTET STRING } + + ---------------------------------------------------------------------------*/ + +int +ldap_create_page_control_value( + LDAP *ld, + unsigned long pagesize, + struct berval *cookie, + struct berval *value ) +{ + BerElement *ber = NULL; + ber_tag_t tag; + struct berval null_cookie = { 0, NULL }; + + if ( ld == NULL || value == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + assert( LDAP_VALID( ld ) ); + + value->bv_val = NULL; + value->bv_len = 0; + + if ( cookie == NULL ) { + cookie = &null_cookie; + } + + ber = ldap_alloc_ber_with_options( ld ); + if ( ber == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; + } + + tag = ber_printf( ber, "{iO}", pagesize, cookie ); + if ( tag == LBER_ERROR ) { + goto error_return; + } + + if ( ber_flatten2( ber, value, 1 ) == -1 ) { + ld->ld_errno = LDAP_NO_MEMORY; + } + + if ( 0 ) { +error_return:; + ld->ld_errno = LDAP_ENCODING_ERROR; + } + + if ( ber != NULL ) { + ber_free( ber, 1 ); + } + + return ld->ld_errno; +} + + +/* --------------------------------------------------------------------------- + ldap_create_page_control + + Create and encode a page control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + pagesize (IN) The number of entries to return per page. + + cookie (IN) Opaque structure used by the server to track its + location in the search results. Pass in NULL on the + first call. + + iscritical (IN) 0 - The control is not critical to the operation. + non-zero - The control is critical to the operation. + + ctrlp (OUT) Returns a pointer to the LDAPControl created. This + control SHOULD be freed by calling ldap_control_free() + when done. + + Ber encoding + + pagedResultsControl ::= SEQUENCE { + controlType 1.2.840.113556.1.4.319, + criticality BOOLEAN DEFAULT FALSE, + controlValue searchControlValue } + + searchControlValue ::= SEQUENCE { + size INTEGER (0..maxInt), + -- requested page size from client + -- result set size estimate from server + cookie OCTET STRING } + + ---------------------------------------------------------------------------*/ + +int +ldap_create_page_control( + LDAP *ld, + unsigned long pagesize, + struct berval *cookie, + int iscritical, + LDAPControl **ctrlp ) +{ + struct berval value; + + if ( ctrlp == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + ld->ld_errno = ldap_create_page_control_value( ld, pagesize, cookie, &value ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = ldap_create_control( LDAP_CONTROL_PAGEDRESULTS, + NULL, iscritical, ctrlp ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + (*ctrlp)->ldctl_value = value; + } else { + LDAP_FREE( value.bv_val ); + } + } + + return ld->ld_errno; +} + + +/* --------------------------------------------------------------------------- + ldap_parse_pageresponse_control + + Decode a page control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + ctrls (IN) The address of a NULL-terminated array of + LDAPControl structures, typically obtained by a + call to ldap_parse_result(). The array SHOULD include + a page control. + + count (OUT) The number of entries returned in the page. + + cookie (OUT) Opaque structure used by the server to track its + location in the search results. Use ldap_memfree() to + free the bv_val member of this structure. + + ---------------------------------------------------------------------------*/ + +int +ldap_parse_pageresponse_control( + LDAP *ld, + LDAPControl *ctrl, + unsigned long *countp, + struct berval *cookie ) +{ + BerElement *ber; + ber_tag_t tag; + ber_int_t count; + + if ( ld == NULL || ctrl == NULL || cookie == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + /* Create a BerElement from the berval returned in the control. */ + ber = ber_init( &ctrl->ldctl_value ); + + if ( ber == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; + } + + /* Extract the count and cookie from the control. */ + tag = ber_scanf( ber, "{io}", &count, cookie ); + ber_free( ber, 1 ); + + if ( tag == LBER_ERROR ) { + ld->ld_errno = LDAP_DECODING_ERROR; + } else { + ld->ld_errno = LDAP_SUCCESS; + + if ( countp != NULL ) { + *countp = (unsigned long)count; + } + } + + return ld->ld_errno; +} + +/* --------------------------------------------------------------------------- + ldap_parse_page_control + + Decode a page control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + ctrls (IN) The address of a NULL-terminated array of + LDAPControl structures, typically obtained by a + call to ldap_parse_result(). The array SHOULD include + a page control. + + count (OUT) The number of entries returned in the page. + + cookie (OUT) Opaque structure used by the server to track its + location in the search results. Use ber_bvfree() to + free it. + + ---------------------------------------------------------------------------*/ + +int +ldap_parse_page_control( + LDAP *ld, + LDAPControl **ctrls, + unsigned long *countp, + struct berval **cookiep ) +{ + struct berval cookie; + int i; + + if ( cookiep == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + if ( ctrls == NULL ) { + ld->ld_errno = LDAP_CONTROL_NOT_FOUND; + return ld->ld_errno; + } + + /* Search the list of control responses for a page control. */ + for ( i = 0; ctrls[i]; i++ ) { + if ( strcmp( LDAP_CONTROL_PAGEDRESULTS, ctrls[ i ]->ldctl_oid ) == 0 ) { + break; + } + } + + /* No page control was found. */ + if ( ctrls[ i ] == NULL ) { + ld->ld_errno = LDAP_CONTROL_NOT_FOUND; + return ld->ld_errno; + } + + ld->ld_errno = ldap_parse_pageresponse_control( ld, ctrls[ i ], countp, &cookie ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + *cookiep = LDAP_MALLOC( sizeof( struct berval * ) ); + if ( *cookiep == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + } else { + **cookiep = cookie; + } + } + + return ld->ld_errno; +} + diff --git a/libraries/libldap/sortctrl.c b/libraries/libldap/sortctrl.c index 0c14a133b3..a2bd69a2fb 100644 --- a/libraries/libldap/sortctrl.c +++ b/libraries/libldap/sortctrl.c @@ -260,9 +260,9 @@ ldap_free_sort_keylist ( LDAPSortKey **keyList ) /* --------------------------------------------------------------------------- - ldap_create_sort_control + ldap_create_sort_control_value - Create and encode the server-side sort control. + Create and encode the value of the server-side sort control. ld (IN) An LDAP session handle, as obtained from a call to ldap_init(). @@ -273,11 +273,8 @@ ldap_free_sort_keylist ( LDAPSortKey **keyList ) consists of an attribute name, ascending/descending flag, and an optional matching rule (OID) to use. - isCritical (IN) 0 - Indicates the control is not critical to the operation. - non-zero - The control is critical to the operation. - - ctrlp (OUT) Returns a pointer to the LDAPControl created. This control - SHOULD be freed by calling ldap_control_free() when done. + value (OUT) Contains the control value; the bv_val member of the berval structure + SHOULD be freed by calling ldap_memfree() when done. Ber encoding @@ -290,68 +287,146 @@ ldap_free_sort_keylist ( LDAPSortKey **keyList ) ---------------------------------------------------------------------------*/ int -ldap_create_sort_control ( +ldap_create_sort_control_value( LDAP *ld, LDAPSortKey **keyList, - int isCritical, - LDAPControl **ctrlp ) + struct berval *value ) { - int i; - BerElement *ber; - ber_tag_t tag; + int i; + BerElement *ber = NULL; + ber_tag_t tag; - - if ( (ld == NULL) || (keyList == NULL) || (ctrlp == NULL) ) { + if ( ld == NULL || keyList == NULL || value == NULL ) { ld->ld_errno = LDAP_PARAM_ERROR; - return(ld->ld_errno); + return ld->ld_errno; } - if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) { + assert( LDAP_VALID( ld ) ); + + value->bv_val = NULL; + value->bv_len = 0; + + ber = ldap_alloc_ber_with_options( ld ); + if ( ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; - return( ld->ld_errno ); + return ld->ld_errno; } - tag = ber_printf(ber, "{" /*}*/); - if (tag == LBER_ERROR) goto exit; + tag = ber_printf( ber, "{" /*}*/ ); + if ( tag == LBER_ERROR ) { + goto error_return; + } - for (i = 0; keyList[i] != NULL; i++) { - tag = ber_printf(ber, "{s" /*}*/, (keyList[i])->attributeType); - if (tag == LBER_ERROR) goto exit; + for ( i = 0; keyList[i] != NULL; i++ ) { + tag = ber_printf( ber, "{s" /*}*/, keyList[i]->attributeType ); + if ( tag == LBER_ERROR ) { + goto error_return; + } - if ((keyList[i])->orderingRule != NULL) { + if ( keyList[i]->orderingRule != NULL ) { tag = ber_printf( ber, "ts", LDAP_MATCHRULE_IDENTIFIER, - (keyList[i])->orderingRule ); + keyList[i]->orderingRule ); - if( tag == LBER_ERROR ) goto exit; + if ( tag == LBER_ERROR ) { + goto error_return; + } } - if ((keyList[i])->reverseOrder) { - tag = ber_printf(ber, "tb", + if ( keyList[i]->reverseOrder ) { + tag = ber_printf( ber, "tb", LDAP_REVERSEORDER_IDENTIFIER, - (keyList[i])->reverseOrder ); + keyList[i]->reverseOrder ); - if( tag == LBER_ERROR ) goto exit; + if ( tag == LBER_ERROR ) { + goto error_return; + } } - tag = ber_printf(ber, /*{*/ "N}"); - if( tag == LBER_ERROR ) goto exit; + tag = ber_printf( ber, /*{*/ "N}" ); + if ( tag == LBER_ERROR ) { + goto error_return; + } } - tag = ber_printf(ber, /*{*/ "N}"); - if( tag == LBER_ERROR ) goto exit; + tag = ber_printf( ber, /*{*/ "N}" ); + if ( tag == LBER_ERROR ) { + goto error_return; + } - ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST, - ber, isCritical, ctrlp); + if ( ber_flatten2( ber, value, 1 ) == -1 ) { + ld->ld_errno = LDAP_NO_MEMORY; + } - ber_free(ber, 1); + if ( 0 ) { +error_return:; + ld->ld_errno = LDAP_ENCODING_ERROR; + } - return(ld->ld_errno); + if ( ber != NULL ) { + ber_free( ber, 1 ); + } -exit: - ber_free(ber, 1); - ld->ld_errno = LDAP_ENCODING_ERROR; - return(ld->ld_errno); + return ld->ld_errno; +} + + +/* --------------------------------------------------------------------------- + ldap_create_sort_control + + Create and encode the server-side sort control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + keyList (IN) Points to a null-terminated array of pointers to + LDAPSortKey structures, containing a description of + each of the sort keys to be used. The description + consists of an attribute name, ascending/descending flag, + and an optional matching rule (OID) to use. + + isCritical (IN) 0 - Indicates the control is not critical to the operation. + non-zero - The control is critical to the operation. + + ctrlp (OUT) Returns a pointer to the LDAPControl created. This control + SHOULD be freed by calling ldap_control_free() when done. + + + Ber encoding + + SortKeyList ::= SEQUENCE OF SEQUENCE { + attributeType AttributeDescription, + orderingRule [0] MatchingRuleId OPTIONAL, + reverseOrder [1] BOOLEAN DEFAULT FALSE } + + ---------------------------------------------------------------------------*/ + +int +ldap_create_sort_control( + LDAP *ld, + LDAPSortKey **keyList, + int isCritical, + LDAPControl **ctrlp ) +{ + struct berval value; + + if ( ctrlp == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + ld->ld_errno = ldap_create_sort_control_value( ld, keyList, &value ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST, + NULL, isCritical, ctrlp ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + (*ctrlp)->ldctl_value = value; + } else { + LDAP_FREE( value.bv_val ); + } + } + + return ld->ld_errno; } @@ -403,15 +478,13 @@ exit: ---------------------------------------------------------------------------*/ int -ldap_parse_sortedresult_control( +ldap_parse_sortresponse_control( LDAP *ld, LDAPControl *ctrl, unsigned long *returnCode, char **attribute ) { BerElement *ber; - LDAPControl *pControl; - int i; ber_tag_t tag, berTag; ber_len_t berLen; diff --git a/libraries/libldap/vlvctrl.c b/libraries/libldap/vlvctrl.c index c8896d4203..ed30953816 100644 --- a/libraries/libldap/vlvctrl.c +++ b/libraries/libldap/vlvctrl.c @@ -57,12 +57,12 @@ are used to construct the value of the control that is created. - ctrlp (OUT) A result parameter that will be assigned the address + value (OUT) A struct berval that contains the value to be assigned to the ldctl_value member of an LDAPControl structure that contains the - VirtualListViewRequest control created by this function. - The memory occupied by the LDAPControl structure + VirtualListViewRequest control. + The bv_val member of the berval structure SHOULD be freed when it is no longer in use by - calling ldap_control_free(). + calling ldap_memfree(). Ber encoding @@ -87,62 +87,151 @@ ---*/ int -ldap_create_vlv_control( LDAP *ld, - LDAPVLVInfo *vlvinfop, - LDAPControl **ctrlp ) +ldap_create_vlv_control_value( + LDAP *ld, + LDAPVLVInfo *vlvinfop, + struct berval *value ) { ber_tag_t tag; BerElement *ber; - assert( ld != NULL ); + if ( ld == NULL || vlvinfop == NULL || value == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + assert( LDAP_VALID( ld ) ); - assert( vlvinfop != NULL ); - assert( ctrlp != NULL ); - if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) { + value->bv_val = NULL; + value->bv_len = 0; + + ber = ldap_alloc_ber_with_options( ld ); + if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; - return(LDAP_NO_MEMORY); + return ld->ld_errno; } - tag = ber_printf(ber, "{ii" /*}*/, + tag = ber_printf( ber, "{ii" /*}*/, vlvinfop->ldvlv_before_count, - vlvinfop->ldvlv_after_count); - if( tag == LBER_ERROR ) goto exit; + vlvinfop->ldvlv_after_count ); + if ( tag == LBER_ERROR ) { + goto error_return; + } - if (vlvinfop->ldvlv_attrvalue == NULL) { - tag = ber_printf(ber, "t{iiN}", + if ( vlvinfop->ldvlv_attrvalue == NULL ) { + tag = ber_printf( ber, "t{iiN}", LDAP_VLVBYINDEX_IDENTIFIER, vlvinfop->ldvlv_offset, - vlvinfop->ldvlv_count); - if( tag == LBER_ERROR ) goto exit; + vlvinfop->ldvlv_count ); + if ( tag == LBER_ERROR ) { + goto error_return; + } } else { - tag = ber_printf(ber, "tO", + tag = ber_printf( ber, "tO", LDAP_VLVBYVALUE_IDENTIFIER, - vlvinfop->ldvlv_attrvalue); - if( tag == LBER_ERROR ) goto exit; + vlvinfop->ldvlv_attrvalue ); + if ( tag == LBER_ERROR ) { + goto error_return; + } } - if (vlvinfop->ldvlv_context) { - tag = ber_printf(ber, "tO", + if ( vlvinfop->ldvlv_context ) { + tag = ber_printf( ber, "tO", LDAP_VLVCONTEXT_IDENTIFIER, - vlvinfop->ldvlv_context); - if( tag == LBER_ERROR ) goto exit; + vlvinfop->ldvlv_context ); + if ( tag == LBER_ERROR ) { + goto error_return; + } } - tag = ber_printf(ber, /*{*/ "N}"); - if( tag == LBER_ERROR ) goto exit; + tag = ber_printf( ber, /*{*/ "N}" ); + if ( tag == LBER_ERROR ) { + goto error_return; + } - ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST, - ber, 1, ctrlp); + if ( ber_flatten2( ber, value, 1 ) == -1 ) { + ld->ld_errno = LDAP_NO_MEMORY; + } - ber_free(ber, 1); - return(ld->ld_errno); + if ( 0 ) { +error_return:; + ld->ld_errno = LDAP_ENCODING_ERROR; + } -exit: - ber_free(ber, 1); - ld->ld_errno = LDAP_ENCODING_ERROR; - return(ld->ld_errno); + if ( ber != NULL ) { + ber_free( ber, 1 ); + } + + return ld->ld_errno; +} + +/*--- + ldap_create_vlv_control + + Create and encode the Virtual List View control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents + are used to construct the value of the control + that is created. + + ctrlp (OUT) A result parameter that will be assigned the address + of an LDAPControl structure that contains the + VirtualListViewRequest control created by this function. + The memory occupied by the LDAPControl structure + SHOULD be freed when it is no longer in use by + calling ldap_control_free(). + + + Ber encoding + + VirtualListViewRequest ::= SEQUENCE { + beforeCount INTEGER (0 .. maxInt), + afterCount INTEGER (0 .. maxInt), + CHOICE { + byoffset [0] SEQUENCE, { + offset INTEGER (0 .. maxInt), + contentCount INTEGER (0 .. maxInt) } + [1] greaterThanOrEqual assertionValue } + contextID OCTET STRING OPTIONAL } + + + Note: The first time the VLV control is created, the ldvlv_context + field of the LDAPVLVInfo structure should be set to NULL. + The context obtained from calling ldap_parse_vlv_control() + should be used as the context in the next ldap_create_vlv_control + call. + + ---*/ + +int +ldap_create_vlv_control( + LDAP *ld, + LDAPVLVInfo *vlvinfop, + LDAPControl **ctrlp ) +{ + struct berval value; + + if ( ctrlp == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST, + NULL, 1, ctrlp ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + (*ctrlp)->ldctl_value = value; + } else { + LDAP_FREE( value.bv_val ); + } + } + + return ld->ld_errno; } @@ -210,8 +299,6 @@ ldap_parse_vlvresponse_control( int *errcodep ) { BerElement *ber; - LDAPControl *pControl; - int i; unsigned long pos, count, err; ber_tag_t tag, berTag; ber_len_t berLen; diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in index 93f725a23a..a049416b66 100644 --- a/libraries/libldap_r/Makefile.in +++ b/libraries/libldap_r/Makefile.in @@ -25,7 +25,7 @@ XXSRCS = apitest.c test.c \ sasl.c sbind.c kbind.c unbind.c cancel.c \ filter.c free.c sort.c passwd.c whoami.c \ getdn.c getentry.c getattr.c getvalues.c addentry.c \ - request.c os-ip.c url.c sortctrl.c vlvctrl.c \ + request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \ init.c options.c print.c string.c util-int.c schema.c \ charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \ turn.c groupings.c txn.c ppolicy.c dds.c @@ -41,7 +41,7 @@ OBJS = threads.lo rdwr.lo tpool.lo rq.lo \ sasl.lo sbind.lo kbind.lo unbind.lo cancel.lo \ filter.lo free.lo sort.lo passwd.lo whoami.lo \ getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \ - request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \ + request.lo os-ip.lo url.lo pagectrl.o sortctrl.lo vlvctrl.lo \ init.lo options.lo print.lo string.lo util-int.lo schema.lo \ charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \ turn.lo groupings.lo txn.lo ppolicy.lo dds.lo -- 2.39.5