Back to index

openldap  2.4.31
pagectrl.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * Copyright 2006 Hans Leidekker
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 #include <ac/stdlib.h>
00021 #include <ac/string.h>
00022 #include <ac/time.h>
00023 
00024 #include "ldap-int.h"
00025 
00026 /* ---------------------------------------------------------------------------
00027     ldap_create_page_control_value
00028 
00029     Create and encode the value of the paged results control (RFC 2696).
00030 
00031     ld          (IN) An LDAP session handle
00032     pagesize    (IN) Page size requested
00033     cookie      (IN) Opaque structure used by the server to track its
00034                      location in the search results.  NULL on the
00035                      first call.
00036     value      (OUT) Control value, SHOULD be freed by calling
00037                                     ldap_memfree() when done.
00038  
00039     pagedResultsControl ::= SEQUENCE {
00040             controlType     1.2.840.113556.1.4.319,
00041             criticality     BOOLEAN DEFAULT FALSE,
00042             controlValue    searchControlValue }
00043 
00044     searchControlValue ::= SEQUENCE {
00045             size            INTEGER (0..maxInt),
00046                                     -- requested page size from client
00047                                     -- result set size estimate from server
00048             cookie          OCTET STRING }
00049 
00050    ---------------------------------------------------------------------------*/
00051 
00052 int
00053 ldap_create_page_control_value(
00054        LDAP *ld,
00055        ber_int_t pagesize,
00056        struct berval *cookie,
00057        struct berval *value )
00058 {
00059        BerElement    *ber = NULL;
00060        ber_tag_t     tag;
00061        struct berval null_cookie = { 0, NULL };
00062 
00063        if ( ld == NULL || value == NULL ||
00064               pagesize < 1 || pagesize > LDAP_MAXINT )
00065        {
00066               if ( ld )
00067                      ld->ld_errno = LDAP_PARAM_ERROR;
00068               return LDAP_PARAM_ERROR;
00069        }
00070 
00071        assert( LDAP_VALID( ld ) );
00072 
00073        value->bv_val = NULL;
00074        value->bv_len = 0;
00075        ld->ld_errno = LDAP_SUCCESS;
00076 
00077        if ( cookie == NULL ) {
00078               cookie = &null_cookie;
00079        }
00080 
00081        ber = ldap_alloc_ber_with_options( ld );
00082        if ( ber == NULL ) {
00083               ld->ld_errno = LDAP_NO_MEMORY;
00084               return ld->ld_errno;
00085        }
00086 
00087        tag = ber_printf( ber, "{iO}", pagesize, cookie );
00088        if ( tag == LBER_ERROR ) {
00089               ld->ld_errno = LDAP_ENCODING_ERROR;
00090               goto done;
00091        }
00092 
00093        if ( ber_flatten2( ber, value, 1 ) == -1 ) {
00094               ld->ld_errno = LDAP_NO_MEMORY;
00095        }
00096 
00097 done:;
00098        if ( ber != NULL ) {
00099               ber_free( ber, 1 );
00100        }
00101 
00102        return ld->ld_errno;
00103 }
00104 
00105 
00106 /* ---------------------------------------------------------------------------
00107     ldap_create_page_control
00108 
00109     Create and encode a page control.
00110 
00111     ld          (IN) An LDAP session handle
00112     pagesize    (IN) Page size requested
00113     cookie      (IN) Opaque structure used by the server to track its
00114                      location in the search results.  NULL on the
00115                      first call.
00116     value      (OUT) Control value, SHOULD be freed by calling
00117                                     ldap_memfree() when done.
00118     iscritical  (IN) Criticality
00119     ctrlp      (OUT) LDAP control, SHOULD be freed by calling
00120                                     ldap_control_free() when done.
00121  
00122     pagedResultsControl ::= SEQUENCE {
00123             controlType     1.2.840.113556.1.4.319,
00124             criticality     BOOLEAN DEFAULT FALSE,
00125             controlValue    searchControlValue }
00126 
00127     searchControlValue ::= SEQUENCE {
00128             size            INTEGER (0..maxInt),
00129                                     -- requested page size from client
00130                                     -- result set size estimate from server
00131             cookie          OCTET STRING }
00132 
00133    ---------------------------------------------------------------------------*/
00134 
00135 int
00136 ldap_create_page_control(
00137        LDAP          *ld,
00138        ber_int_t     pagesize,
00139        struct berval *cookie,
00140        int           iscritical,
00141        LDAPControl   **ctrlp )
00142 {
00143        struct berval value;
00144 
00145        if ( ctrlp == NULL ) {
00146               ld->ld_errno = LDAP_PARAM_ERROR;
00147               return ld->ld_errno;
00148        }
00149 
00150        ld->ld_errno = ldap_create_page_control_value( ld,
00151               pagesize, cookie, &value );
00152        if ( ld->ld_errno == LDAP_SUCCESS ) {
00153               ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
00154                      iscritical, &value, 0, ctrlp );
00155               if ( ld->ld_errno != LDAP_SUCCESS ) {
00156                      LDAP_FREE( value.bv_val );
00157               }
00158        }
00159 
00160        return ld->ld_errno;
00161 }
00162 
00163 
00164 /* ---------------------------------------------------------------------------
00165     ldap_parse_pageresponse_control
00166 
00167     Decode a page control.
00168 
00169     ld          (IN) An LDAP session handle
00170     ctrl        (IN) The page response control
00171     count      (OUT) The number of entries in the page.
00172     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
00173                      free the bv_val member of this structure.
00174 
00175    ---------------------------------------------------------------------------*/
00176 
00177 int
00178 ldap_parse_pageresponse_control(
00179        LDAP *ld,
00180        LDAPControl *ctrl,
00181        ber_int_t *countp,
00182        struct berval *cookie )
00183 {
00184        BerElement *ber;
00185        ber_tag_t tag;
00186        ber_int_t count;
00187 
00188        if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
00189               if ( ld )
00190                      ld->ld_errno = LDAP_PARAM_ERROR;
00191               return LDAP_PARAM_ERROR;
00192        }
00193 
00194        /* Create a BerElement from the berval returned in the control. */
00195        ber = ber_init( &ctrl->ldctl_value );
00196 
00197        if ( ber == NULL ) {
00198               ld->ld_errno = LDAP_NO_MEMORY;
00199               return ld->ld_errno;
00200        }
00201 
00202        /* Extract the count and cookie from the control. */
00203        tag = ber_scanf( ber, "{io}", &count, cookie );
00204         ber_free( ber, 1 );
00205 
00206        if ( tag == LBER_ERROR ) {
00207               ld->ld_errno = LDAP_DECODING_ERROR;
00208        } else {
00209               ld->ld_errno = LDAP_SUCCESS;
00210 
00211               if ( countp != NULL ) {
00212                      *countp = (unsigned long)count;
00213               }
00214        }
00215 
00216        return ld->ld_errno;
00217 }
00218 
00219 /* ---------------------------------------------------------------------------
00220     ldap_parse_page_control
00221 
00222     Decode a page control.
00223 
00224     ld          (IN) An LDAP session handle
00225     ctrls       (IN) Response controls
00226     count      (OUT) The number of entries in the page.
00227     cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
00228                      free the bv_val member of this structure.
00229 
00230    ---------------------------------------------------------------------------*/
00231 
00232 int
00233 ldap_parse_page_control(
00234        LDAP          *ld,
00235        LDAPControl   **ctrls,
00236        ber_int_t *countp,
00237        struct berval **cookiep )
00238 {
00239        LDAPControl *c;
00240        struct berval cookie;
00241 
00242        if ( cookiep == NULL ) {
00243               ld->ld_errno = LDAP_PARAM_ERROR;
00244               return ld->ld_errno;
00245        }
00246 
00247        if ( ctrls == NULL ) {
00248               ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
00249               return ld->ld_errno;
00250        }
00251 
00252        c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
00253        if ( c == NULL ) {
00254               /* No page control was found. */
00255               ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
00256               return ld->ld_errno;
00257        }
00258 
00259        ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );
00260        if ( ld->ld_errno == LDAP_SUCCESS ) {
00261               *cookiep = LDAP_MALLOC( sizeof( struct berval ) );
00262               if ( *cookiep == NULL ) {
00263                      ld->ld_errno = LDAP_NO_MEMORY;
00264               } else {
00265                      **cookiep = cookie;
00266               }
00267        }
00268 
00269        return ld->ld_errno;
00270 }
00271