]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/nssov/nss-ldapd/compat/pagectrl.c
nss overlay
[openldap] / contrib / slapd-modules / nssov / nss-ldapd / compat / pagectrl.c
1 /*
2    pagectrl.c - provide a replacement ldap_create_page_control() function.
3    This file was part of the nss_ldap library which has been
4    forked into the nss-ldapd library.
5
6    Copyright (C) 2002 Max Caines
7    This software is not subject to any license of the University
8    of Wolverhampton.
9
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2.1 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301 USA
24 */
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <lber.h>
33 #include <ldap.h>
34
35 #include "pagectrl.h"
36
37 #ifndef LDAP_CONTROL_PAGE_OID
38 #define LDAP_CONTROL_PAGE_OID           "1.2.840.113556.1.4.319"
39 #endif
40
41 #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
42 /*---
43    ldap_create_page_control
44
45    Create and encode the Paged Results control.
46
47    ld        (IN)  An LDAP session handle, as obtained from a call to
48                                    ldap_init().
49
50    pagesize  (IN)  The number of entries to return in each page
51
52    cookiep   (IN)  Pointer to a berVal structure that the server uses to
53                                    determine the current location in the
54                                    result set (opaque). Set to NULL the
55                                    first time.
56
57    iscritical (IN) Is this control critical to the search?
58
59    ctrlp     (OUT) A result parameter that will be assigned the address
60                                    of an LDAPControl structure that contains the
61                                    PagedResult control created by this function.
62                                    The memory occupied by the LDAPControl structure
63                                    SHOULD be freed when it is no longer in use by
64                                    calling ldap_control_free().
65
66
67    Ber encoding
68
69    PageResult ::= SEQUENCE {
70                 pageSize     INTEGER
71                 cookie       OCTET STRING }
72
73
74    Note:  The first time the Page control is created, the cookie
75                   should be set to a zero-length string. The cookie obtained
76                   from calling ldap_parse_page_control() should be used as
77                   the cookie in the next ldap_create_page_control call.
78
79  ---*/
80
81 int
82 ldap_create_page_control (LDAP * ld,
83                           unsigned long pagesize,
84                           struct berval *cookiep,
85                           int iscritical, LDAPControl ** ctrlp)
86 {
87   ber_tag_t tag;
88   BerElement *ber;
89   BerElement *ldap_alloc_ber_with_options (LDAP * ld);
90   int rc;
91
92   if ((ld == NULL) || (ctrlp == NULL))
93     {
94       return (LDAP_PARAM_ERROR);
95     }
96
97   if ((ber = ldap_alloc_ber_with_options (ld)) == NULL)
98     {
99       return (LDAP_NO_MEMORY);
100     }
101
102   tag = ber_printf (ber, "{i", pagesize);
103   if (tag == LBER_ERROR)
104     goto exit;
105
106   if (cookiep == NULL)
107     tag = ber_printf (ber, "o", "", 0);
108   else
109     tag = ber_printf (ber, "O", cookiep);
110   if (tag == LBER_ERROR)
111     goto exit;
112
113   tag = ber_printf (ber, /*{ */ "N}");
114   if (tag == LBER_ERROR)
115     goto exit;
116
117   rc = ldap_create_control (LDAP_CONTROL_PAGE_OID, ber, iscritical, ctrlp);
118
119   ber_free (ber, 1);
120   return (rc);
121
122 exit:
123   ber_free (ber, 1);
124   return (LDAP_ENCODING_ERROR);
125 }
126 #endif /* not HAVE_LDAP_CREATE_PAGE_CONTROL */
127
128 #ifndef HAVE_LDAP_PARSE_PAGE_CONTROL
129 /*---
130    ldap_parse_page_control
131
132    Decode the Virtual List View control return information.
133
134    ld           (IN)   An LDAP session handle.
135
136    ctrls        (IN)   The address of a NULL-terminated array of
137                                            LDAPControl structures, typically obtained
138                                            by a call to ldap_parse_result().
139
140    list_countp  (OUT)  This result parameter is filled in with the number
141                                            of entries returned in this page
142
143    cookiep      (OUT)  This result parameter is filled in with the address
144                                            of a struct berval that contains the server-
145                                            generated cookie.
146                                            The returned cookie SHOULD be used in the next call
147                                            to create a Page sort control.  The struct berval
148                                            returned SHOULD be disposed of by calling ber_bvfree()
149                                            when it is no longer needed.
150
151 ---*/
152 int
153 ldap_parse_page_control (LDAP * ld,
154                          LDAPControl ** ctrls,
155                          unsigned long *list_countp, struct berval **cookiep)
156 {
157   BerElement *ber;
158   LDAPControl *pControl;
159   int i;
160   unsigned long count;
161   ber_tag_t tag;
162
163   if (cookiep)
164     {
165       *cookiep = NULL;          /* Make sure we return a NULL if error occurs. */
166     }
167
168   if (ld == NULL)
169     {
170       return (LDAP_PARAM_ERROR);
171     }
172
173   if (ctrls == NULL)
174     {
175       return (LDAP_CONTROL_NOT_FOUND);
176     }
177
178   /* Search the list of control responses for a Page control. */
179   for (i = 0; ctrls[i]; i++)
180     {
181       pControl = ctrls[i];
182       if (!strcmp (LDAP_CONTROL_PAGE_OID, pControl->ldctl_oid))
183         goto foundPageControl;
184     }
185
186   /* No page control was found. */
187   return (LDAP_CONTROL_NOT_FOUND);
188
189 foundPageControl:
190   /* Create a BerElement from the berval returned in the control. */
191   ber = ber_init (&pControl->ldctl_value);
192
193   if (ber == NULL)
194     {
195       return (LDAP_NO_MEMORY);
196     }
197
198   /* Extract the data returned in the control. */
199   tag = ber_scanf (ber, "{iO" /*} */ , &count, cookiep);
200
201   if (tag == LBER_ERROR)
202     {
203       ber_free (ber, 1);
204       return (LDAP_DECODING_ERROR);
205     }
206
207   ber_free (ber, 1);
208
209   /* Return data to the caller for items that were requested. */
210   if (list_countp)
211     {
212       *list_countp = count;
213     }
214
215   return (LDAP_SUCCESS);
216 }
217 #endif /* not HAVE_LDAP_PARSE_PAGE_CONTROL */