Blame compat/pagectrl.c

Packit 6bd9ab
/*
Packit 6bd9ab
   pagectrl.c - provide a replacement ldap_create_page_control() function.
Packit 6bd9ab
   This file was part of the nss_ldap library which has been
Packit 6bd9ab
   forked into the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2002 Max Caines
Packit 6bd9ab
   This software is not subject to any license of the University
Packit 6bd9ab
   of Wolverhampton.
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <stdio.h>
Packit 6bd9ab
#include <stdlib.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <time.h>
Packit 6bd9ab
#include <lber.h>
Packit 6bd9ab
#include <ldap.h>
Packit 6bd9ab
Packit 6bd9ab
#include "compat/ldap_compat.h"
Packit 6bd9ab
Packit 6bd9ab
#ifndef LDAP_CONTROL_PAGE_OID
Packit 6bd9ab
#define LDAP_CONTROL_PAGE_OID           "1.2.840.113556.1.4.319"
Packit 6bd9ab
#endif
Packit 6bd9ab
Packit 6bd9ab
#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
Packit 6bd9ab
/*---
Packit 6bd9ab
   ldap_create_page_control
Packit 6bd9ab
Packit 6bd9ab
   Create and encode the Paged Results control.
Packit 6bd9ab
Packit 6bd9ab
   ld        (IN)  An LDAP session handle, as obtained from a call to
Packit 6bd9ab
                                   ldap_init().
Packit 6bd9ab
Packit 6bd9ab
   pagesize  (IN)  The number of entries to return in each page
Packit 6bd9ab
Packit 6bd9ab
   cookiep   (IN)  Pointer to a berVal structure that the server uses to
Packit 6bd9ab
                                   determine the current location in the
Packit 6bd9ab
                                   result set (opaque). Set to NULL the
Packit 6bd9ab
                                   first time.
Packit 6bd9ab
Packit 6bd9ab
   iscritical (IN) Is this control critical to the search?
Packit 6bd9ab
Packit 6bd9ab
   ctrlp     (OUT) A result parameter that will be assigned the address
Packit 6bd9ab
                                   of an LDAPControl structure that contains the
Packit 6bd9ab
                                   PagedResult control created by this function.
Packit 6bd9ab
                                   The memory occupied by the LDAPControl structure
Packit 6bd9ab
                                   SHOULD be freed when it is no longer in use by
Packit 6bd9ab
                                   calling ldap_control_free().
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
   Ber encoding
Packit 6bd9ab
Packit 6bd9ab
   PageResult ::= SEQUENCE {
Packit 6bd9ab
                pageSize     INTEGER
Packit 6bd9ab
                cookie       OCTET STRING }
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
   Note:  The first time the Page control is created, the cookie
Packit 6bd9ab
                  should be set to a zero-length string. The cookie obtained
Packit 6bd9ab
                  from calling ldap_parse_page_control() should be used as
Packit 6bd9ab
                  the cookie in the next ldap_create_page_control call.
Packit 6bd9ab
Packit 6bd9ab
 ---*/
Packit 6bd9ab
Packit 6bd9ab
int
Packit 6bd9ab
ldap_create_page_control (LDAP * ld,
Packit 6bd9ab
                          unsigned long pagesize,
Packit 6bd9ab
                          struct berval *cookiep,
Packit 6bd9ab
                          int iscritical, LDAPControl ** ctrlp)
Packit 6bd9ab
{
Packit 6bd9ab
  ber_tag_t tag;
Packit 6bd9ab
  BerElement *ber;
Packit 6bd9ab
  BerElement *ldap_alloc_ber_with_options (LDAP * ld);
Packit 6bd9ab
  int rc;
Packit 6bd9ab
Packit 6bd9ab
  if ((ld == NULL) || (ctrlp == NULL))
Packit 6bd9ab
    {
Packit 6bd9ab
      return (LDAP_PARAM_ERROR);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  if ((ber = ldap_alloc_ber_with_options (ld)) == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      return (LDAP_NO_MEMORY);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  tag = ber_printf (ber, "{i", pagesize);
Packit 6bd9ab
  if (tag == LBER_ERROR)
Packit 6bd9ab
    goto exit;
Packit 6bd9ab
Packit 6bd9ab
  if (cookiep == NULL)
Packit 6bd9ab
    tag = ber_printf (ber, "o", "", 0);
Packit 6bd9ab
  else
Packit 6bd9ab
    tag = ber_printf (ber, "O", cookiep);
Packit 6bd9ab
  if (tag == LBER_ERROR)
Packit 6bd9ab
    goto exit;
Packit 6bd9ab
Packit 6bd9ab
  tag = ber_printf (ber, /*{ */ "N}");
Packit 6bd9ab
  if (tag == LBER_ERROR)
Packit 6bd9ab
    goto exit;
Packit 6bd9ab
Packit 6bd9ab
  rc = ldap_create_control (LDAP_CONTROL_PAGE_OID, ber, iscritical, ctrlp);
Packit 6bd9ab
Packit 6bd9ab
  ber_free (ber, 1);
Packit 6bd9ab
  return (rc);
Packit 6bd9ab
Packit 6bd9ab
exit:
Packit 6bd9ab
  ber_free (ber, 1);
Packit 6bd9ab
  return (LDAP_ENCODING_ERROR);
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* not HAVE_LDAP_CREATE_PAGE_CONTROL */
Packit 6bd9ab
Packit 6bd9ab
#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL
Packit 6bd9ab
/*---
Packit 6bd9ab
   ldap_parse_page_control
Packit 6bd9ab
Packit 6bd9ab
   Decode the Virtual List View control return information.
Packit 6bd9ab
Packit 6bd9ab
   ld           (IN)   An LDAP session handle.
Packit 6bd9ab
Packit 6bd9ab
   ctrls        (IN)   The address of a NULL-terminated array of
Packit 6bd9ab
                                           LDAPControl structures, typically obtained
Packit 6bd9ab
                                           by a call to ldap_parse_result().
Packit 6bd9ab
Packit 6bd9ab
   list_countp  (OUT)  This result parameter is filled in with the number
Packit 6bd9ab
                                           of entries returned in this page
Packit 6bd9ab
Packit 6bd9ab
   cookiep      (OUT)  This result parameter is filled in with the address
Packit 6bd9ab
                                           of a struct berval that contains the server-
Packit 6bd9ab
                                           generated cookie.
Packit 6bd9ab
                                           The returned cookie SHOULD be used in the next call
Packit 6bd9ab
                                           to create a Page sort control.  The struct berval
Packit 6bd9ab
                                           returned SHOULD be disposed of by calling ber_bvfree()
Packit 6bd9ab
                                           when it is no longer needed.
Packit 6bd9ab
Packit 6bd9ab
---*/
Packit 6bd9ab
int
Packit 6bd9ab
ldap_parse_page_control (LDAP * ld,
Packit 6bd9ab
                         LDAPControl ** ctrls,
Packit 6bd9ab
                         unsigned long *list_countp, struct berval **cookiep)
Packit 6bd9ab
{
Packit 6bd9ab
  BerElement *ber;
Packit 6bd9ab
  LDAPControl *pControl;
Packit 6bd9ab
  int i;
Packit 6bd9ab
  unsigned long count;
Packit 6bd9ab
  ber_tag_t tag;
Packit 6bd9ab
Packit 6bd9ab
  if (cookiep)
Packit 6bd9ab
    {
Packit 6bd9ab
      *cookiep = NULL;          /* Make sure we return a NULL if error occurs. */
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  if (ld == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      return (LDAP_PARAM_ERROR);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  if (ctrls == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      return (LDAP_CONTROL_NOT_FOUND);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  /* Search the list of control responses for a Page control. */
Packit 6bd9ab
  for (i = 0; ctrls[i]; i++)
Packit 6bd9ab
    {
Packit 6bd9ab
      pControl = ctrls[i];
Packit 6bd9ab
      if (!strcmp (LDAP_CONTROL_PAGE_OID, pControl->ldctl_oid))
Packit 6bd9ab
        goto foundPageControl;
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  /* No page control was found. */
Packit 6bd9ab
  return (LDAP_CONTROL_NOT_FOUND);
Packit 6bd9ab
Packit 6bd9ab
foundPageControl:
Packit 6bd9ab
  /* Create a BerElement from the berval returned in the control. */
Packit 6bd9ab
  ber = ber_init (&pControl->ldctl_value);
Packit 6bd9ab
Packit 6bd9ab
  if (ber == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      return (LDAP_NO_MEMORY);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  /* Extract the data returned in the control. */
Packit 6bd9ab
  tag = ber_scanf (ber, "{iO" /*} */ , &count, cookiep);
Packit 6bd9ab
Packit 6bd9ab
  if (tag == LBER_ERROR)
Packit 6bd9ab
    {
Packit 6bd9ab
      ber_free (ber, 1);
Packit 6bd9ab
      return (LDAP_DECODING_ERROR);
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  ber_free (ber, 1);
Packit 6bd9ab
Packit 6bd9ab
  /* Return data to the caller for items that were requested. */
Packit 6bd9ab
  if (list_countp)
Packit 6bd9ab
    {
Packit 6bd9ab
      *list_countp = count;
Packit 6bd9ab
    }
Packit 6bd9ab
Packit 6bd9ab
  return (LDAP_SUCCESS);
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* not HAVE_LDAP_PARSE_PAGE_CONTROL */