]> git.sur5r.net Git - openldap/commitdiff
rework API functions to create/parse controls; add client API functions to handle...
authorPierangelo Masarati <ando@openldap.org>
Sun, 8 Jan 2006 22:03:30 +0000 (22:03 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 8 Jan 2006 22:03:30 +0000 (22:03 +0000)
include/ldap.h
libraries/libldap/Makefile.in
libraries/libldap/pagectrl.c [new file with mode: 0644]
libraries/libldap/sortctrl.c
libraries/libldap/vlvctrl.c
libraries/libldap_r/Makefile.in

index 24133f614f215ba90162d1ba9182be8ecd7f8e11..ef834212576904be552a6c830785b3c683e7b651 100644 (file)
@@ -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,
index 3e5028cf5ba8b422e68742535ef8eb26595ec85d..2cb20610ea97f6c51d509254c9c18fb99d1970fc 100644 (file)
@@ -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 (file)
index 0000000..67f648c
--- /dev/null
@@ -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;
+}
+
index 0c14a133b36683c0728a6c72c86dabd62c23e3b9..a2bd69a2fb7a1245f1b67bea1ff98135035ba47b 100644 (file)
@@ -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;
 
index c8896d420370884d005ce680c458d803a06ec535..ed30953816270a7a408e3f94f7a0848589dc933f 100644 (file)
                                   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
  ---*/
 
 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;
index 93f725a23abfb6869dcedf049e26b152ad8916ab..a049416b66fdfec37318db93d05dc8d6668ea1c7 100644 (file)
@@ -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