mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-28 02:29:34 -05:00
rework API functions to create/parse controls; add client API functions to handle RFC2696 paged results (ITS#4314; patch from Hans Leidekker with changes)
This commit is contained in:
parent
32f75fe4f2
commit
de79a7bfec
6 changed files with 642 additions and 111 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
324
libraries/libldap/pagectrl.c
Normal file
324
libraries/libldap/pagectrl.c
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* 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
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* 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 <stdio.h>
|
||||
#include <ac/stdlib.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
@ -259,6 +259,118 @@ ldap_free_sort_keylist ( LDAPSortKey **keyList )
|
|||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
ldap_create_sort_control_value
|
||||
|
||||
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().
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
SortKeyList ::= SEQUENCE OF SEQUENCE {
|
||||
attributeType AttributeDescription,
|
||||
orderingRule [0] MatchingRuleId OPTIONAL,
|
||||
reverseOrder [1] BOOLEAN DEFAULT FALSE }
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
ldap_create_sort_control_value(
|
||||
LDAP *ld,
|
||||
LDAPSortKey **keyList,
|
||||
struct berval *value )
|
||||
{
|
||||
int i;
|
||||
BerElement *ber = NULL;
|
||||
ber_tag_t tag;
|
||||
|
||||
if ( ld == NULL || keyList == 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;
|
||||
|
||||
ber = ldap_alloc_ber_with_options( ld );
|
||||
if ( ber == NULL) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
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 error_return;
|
||||
}
|
||||
|
||||
if ( keyList[i]->orderingRule != NULL ) {
|
||||
tag = ber_printf( ber, "ts",
|
||||
LDAP_MATCHRULE_IDENTIFIER,
|
||||
keyList[i]->orderingRule );
|
||||
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( keyList[i]->reverseOrder ) {
|
||||
tag = ber_printf( ber, "tb",
|
||||
LDAP_REVERSEORDER_IDENTIFIER,
|
||||
keyList[i]->reverseOrder );
|
||||
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
tag = ber_printf( ber, /*{*/ "N}" );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
tag = ber_printf( ber, /*{*/ "N}" );
|
||||
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_sort_control
|
||||
|
||||
|
|
@ -290,68 +402,31 @@ ldap_free_sort_keylist ( LDAPSortKey **keyList )
|
|||
---------------------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
ldap_create_sort_control (
|
||||
ldap_create_sort_control(
|
||||
LDAP *ld,
|
||||
LDAPSortKey **keyList,
|
||||
int isCritical,
|
||||
LDAPControl **ctrlp )
|
||||
{
|
||||
int i;
|
||||
BerElement *ber;
|
||||
ber_tag_t tag;
|
||||
struct berval value;
|
||||
|
||||
|
||||
if ( (ld == NULL) || (keyList == NULL) || (ctrlp == NULL) ) {
|
||||
if ( ctrlp == NULL ) {
|
||||
ld->ld_errno = LDAP_PARAM_ERROR;
|
||||
return(ld->ld_errno);
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return( ld->ld_errno );
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, "{" /*}*/);
|
||||
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 exit;
|
||||
|
||||
if ((keyList[i])->orderingRule != NULL) {
|
||||
tag = ber_printf( ber, "ts",
|
||||
LDAP_MATCHRULE_IDENTIFIER,
|
||||
(keyList[i])->orderingRule );
|
||||
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
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 );
|
||||
}
|
||||
|
||||
if ((keyList[i])->reverseOrder) {
|
||||
tag = ber_printf(ber, "tb",
|
||||
LDAP_REVERSEORDER_IDENTIFIER,
|
||||
(keyList[i])->reverseOrder );
|
||||
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, /*{*/ "N}");
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, /*{*/ "N}");
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
|
||||
ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST,
|
||||
ber, isCritical, ctrlp);
|
||||
|
||||
ber_free(ber, 1);
|
||||
|
||||
return(ld->ld_errno);
|
||||
|
||||
exit:
|
||||
ber_free(ber, 1);
|
||||
ld->ld_errno = LDAP_ENCODING_ERROR;
|
||||
return(ld->ld_errno);
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,127 @@
|
|||
#define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
|
||||
|
||||
|
||||
/*---
|
||||
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.
|
||||
|
||||
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.
|
||||
The bv_val member of the berval structure
|
||||
SHOULD be freed when it is no longer in use by
|
||||
calling ldap_memfree().
|
||||
|
||||
|
||||
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_value(
|
||||
LDAP *ld,
|
||||
LDAPVLVInfo *vlvinfop,
|
||||
struct berval *value )
|
||||
{
|
||||
ber_tag_t tag;
|
||||
BerElement *ber;
|
||||
|
||||
if ( ld == NULL || vlvinfop == 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;
|
||||
|
||||
ber = ldap_alloc_ber_with_options( ld );
|
||||
if ( ber == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
tag = ber_printf( ber, "{ii" /*}*/,
|
||||
vlvinfop->ldvlv_before_count,
|
||||
vlvinfop->ldvlv_after_count );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
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 error_return;
|
||||
}
|
||||
|
||||
} else {
|
||||
tag = ber_printf( ber, "tO",
|
||||
LDAP_VLVBYVALUE_IDENTIFIER,
|
||||
vlvinfop->ldvlv_attrvalue );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( vlvinfop->ldvlv_context ) {
|
||||
tag = ber_printf( ber, "tO",
|
||||
LDAP_VLVCONTEXT_IDENTIFIER,
|
||||
vlvinfop->ldvlv_context );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
tag = ber_printf( ber, /*{*/ "N}" );
|
||||
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_vlv_control
|
||||
|
||||
|
|
@ -87,62 +208,30 @@
|
|||
---*/
|
||||
|
||||
int
|
||||
ldap_create_vlv_control( LDAP *ld,
|
||||
LDAPVLVInfo *vlvinfop,
|
||||
LDAPControl **ctrlp )
|
||||
ldap_create_vlv_control(
|
||||
LDAP *ld,
|
||||
LDAPVLVInfo *vlvinfop,
|
||||
LDAPControl **ctrlp )
|
||||
{
|
||||
ber_tag_t tag;
|
||||
BerElement *ber;
|
||||
struct berval value;
|
||||
|
||||
assert( ld != NULL );
|
||||
assert( LDAP_VALID( ld ) );
|
||||
assert( vlvinfop != NULL );
|
||||
assert( ctrlp != NULL );
|
||||
|
||||
if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return(LDAP_NO_MEMORY);
|
||||
if ( ctrlp == NULL ) {
|
||||
ld->ld_errno = LDAP_PARAM_ERROR;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, "{ii" /*}*/,
|
||||
vlvinfop->ldvlv_before_count,
|
||||
vlvinfop->ldvlv_after_count);
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
tag = ber_printf(ber, "tO",
|
||||
LDAP_VLVBYVALUE_IDENTIFIER,
|
||||
vlvinfop->ldvlv_attrvalue);
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
if (vlvinfop->ldvlv_context) {
|
||||
tag = ber_printf(ber, "tO",
|
||||
LDAP_VLVCONTEXT_IDENTIFIER,
|
||||
vlvinfop->ldvlv_context);
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, /*{*/ "N}");
|
||||
if( tag == LBER_ERROR ) goto exit;
|
||||
|
||||
ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
|
||||
ber, 1, ctrlp);
|
||||
|
||||
ber_free(ber, 1);
|
||||
return(ld->ld_errno);
|
||||
|
||||
exit:
|
||||
ber_free(ber, 1);
|
||||
ld->ld_errno = LDAP_ENCODING_ERROR;
|
||||
return(ld->ld_errno);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue