]> git.sur5r.net Git - openldap/blob - libraries/libldap/vlvctrl.c
Don't use default binddn when password is empty
[openldap] / libraries / libldap / vlvctrl.c
1 /*
2  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
6 /*---
7  * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
8  *
9  * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
10  * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
11  * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
12  * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
13  * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
14  * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
15  * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
16  * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
17  *---*/
18 /* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
19  * can be found in the file "build/LICENSE-2.0.1" in this distribution
20  * of OpenLDAP Software.
21  */
22
23 #include "portable.h"
24
25 #include <stdio.h>
26 #include <ac/stdlib.h>
27 #include <ac/string.h>
28 #include <ac/time.h>
29
30 #include "ldap-int.h"
31
32 #define LDAP_VLVBYINDEX_IDENTIFIER     0xa0L
33 #define LDAP_VLVBYVALUE_IDENTIFIER     0x81L
34 #define LDAP_VLVCONTEXT_IDENTIFIER     0x04L
35
36
37 /*---
38    ldap_create_vlv_control
39    
40    Create and encode the Virtual List View control.
41
42    ld        (IN)  An LDAP session handle, as obtained from a call to
43                                    ldap_init().
44    
45    vlvinfop  (IN)  The address of an LDAPVLVInfo structure whose contents 
46                                    are used to construct the value of the control
47                                    that is created.
48    
49    ctrlp     (OUT) A result parameter that will be assigned the address
50                                    of an LDAPControl structure that contains the 
51                                    VirtualListViewRequest control created by this function.
52                                    The memory occupied by the LDAPControl structure
53                                    SHOULD be freed when it is no longer in use by
54                                    calling ldap_control_free().
55                                           
56    
57    Ber encoding
58    
59    VirtualListViewRequest ::= SEQUENCE {
60                 beforeCount  INTEGER (0 .. maxInt),
61                 afterCount   INTEGER (0 .. maxInt),
62                 CHOICE {
63                                 byoffset [0] SEQUENCE, {
64                                 offset        INTEGER (0 .. maxInt),
65                                 contentCount  INTEGER (0 .. maxInt) }
66                                 [1] greaterThanOrEqual assertionValue }
67                 contextID     OCTET STRING OPTIONAL }
68           
69    
70    Note:  The first time the VLV control is created, the ldvlv_context
71                   field of the LDAPVLVInfo structure should be set to NULL.
72                   The context obtained from calling ldap_parse_vlv_control()
73                   should be used as the context in the next ldap_create_vlv_control
74                   call.
75
76  ---*/
77
78 int
79 ldap_create_vlv_control( LDAP *ld,
80                                                  LDAPVLVInfo *vlvinfop,
81                                                  LDAPControl **ctrlp )
82 {
83         ber_tag_t tag;
84         BerElement *ber;
85
86         assert( ld != NULL );
87         assert( LDAP_VALID( ld ) );
88         assert( vlvinfop != NULL );
89         assert( ctrlp != NULL );
90
91         if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
92                 ld->ld_errno = LDAP_NO_MEMORY;
93                 return(LDAP_NO_MEMORY);
94         }
95
96         tag = ber_printf(ber, "{ii" /*}*/,
97                 vlvinfop->ldvlv_before_count,
98                 vlvinfop->ldvlv_after_count);
99         if( tag == LBER_ERROR ) goto exit;
100
101         if (vlvinfop->ldvlv_attrvalue == NULL) {
102                 tag = ber_printf(ber, "t{iiN}",
103                         LDAP_VLVBYINDEX_IDENTIFIER,
104                         vlvinfop->ldvlv_offset,
105                         vlvinfop->ldvlv_count);
106                 if( tag == LBER_ERROR ) goto exit;
107
108         } else {
109                 tag = ber_printf(ber, "tO",
110                         LDAP_VLVBYVALUE_IDENTIFIER,
111                         vlvinfop->ldvlv_attrvalue);
112                 if( tag == LBER_ERROR ) goto exit;
113         }
114
115         if (vlvinfop->ldvlv_context) {
116                 tag = ber_printf(ber, "tO",
117                         LDAP_VLVCONTEXT_IDENTIFIER,
118                         vlvinfop->ldvlv_context);
119                 if( tag == LBER_ERROR ) goto exit;
120         }
121
122         tag = ber_printf(ber, /*{*/ "N}"); 
123         if( tag == LBER_ERROR ) goto exit;
124
125         ld->ld_errno = ldap_create_control(     LDAP_CONTROL_VLVREQUEST,
126                 ber, 1, ctrlp);
127
128         ber_free(ber, 1);
129         return(ld->ld_errno);
130
131 exit:
132         ber_free(ber, 1);
133         ld->ld_errno = LDAP_ENCODING_ERROR;
134         return(ld->ld_errno);
135 }
136
137
138 /*---
139    ldap_parse_vlv_control
140    
141    Decode the Virtual List View control return information.
142
143    ld           (IN)   An LDAP session handle.
144    
145    ctrls        (IN)   The address of a NULL-terminated array of 
146                                            LDAPControl structures, typically obtained 
147                                            by a call to ldap_parse_result().
148    
149    target_posp  (OUT)  This result parameter is filled in with the list
150                                            index of the target entry.  If this parameter is
151                                            NULL, the target position is not returned.
152    
153    list_countp  (OUT)  This result parameter is filled in with the server's
154                                            estimate of the size of the list.  If this parameter
155                                            is NULL, the size is not returned.
156    
157    contextp     (OUT)  This result parameter is filled in with the address
158                                            of a struct berval that contains the server-
159                                            generated context identifier if one was returned by
160                                            the server.  If the server did not return a context
161                                            identifier, this parameter will be set to NULL, even
162                                            if an error occured.
163                                            The returned context SHOULD be used in the next call
164                                            to create a VLV sort control.  The struct berval
165                                            returned SHOULD be disposed of by calling ber_bvfree()
166                                            when it is no longer needed.  If NULL is passed for
167                                            contextp, the context identifier is not returned.
168    
169    errcodep     (OUT)  This result parameter is filled in with the VLV
170                                            result code.  If this parameter is NULL, the result
171                                            code is not returned.  
172    
173    
174    Ber encoding
175    
176    VirtualListViewResponse ::= SEQUENCE {
177                 targetPosition    INTEGER (0 .. maxInt),
178                 contentCount     INTEGER (0 .. maxInt),
179                 virtualListViewResult ENUMERATED {
180                 success (0),
181                 operatonsError (1),
182                 unwillingToPerform (53),
183                 insufficientAccessRights (50),
184                 busy (51),
185                 timeLimitExceeded (3),
186                 adminLimitExceeded (11),
187                 sortControlMissing (60),
188                 offsetRangeError (61),
189                 other (80) },
190                 contextID     OCTET STRING OPTIONAL }
191    
192 ---*/
193
194 int
195 ldap_parse_vlv_control(
196         LDAP           *ld,
197         LDAPControl    **ctrls,
198         unsigned long  *target_posp,
199         unsigned long  *list_countp,
200         struct berval  **contextp,
201         int            *errcodep )
202 {
203         BerElement  *ber;
204         LDAPControl *pControl;
205         int i;
206         unsigned long pos, count, err;
207         ber_tag_t tag, berTag;
208         ber_len_t berLen;
209
210         assert( ld != NULL );
211         assert( LDAP_VALID( ld ) );
212
213         if (contextp) {
214                 *contextp = NULL;        /* Make sure we return a NULL if error occurs. */
215         }
216
217         if (ctrls == NULL) {
218                 ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
219                 return(ld->ld_errno);
220         }
221
222         /* Search the list of control responses for a VLV control. */
223         for (i=0; ctrls[i]; i++) {
224                 pControl = ctrls[i];
225                 if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
226                         goto foundVLVControl;
227         }
228
229         /* No sort control was found. */
230         ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
231         return(ld->ld_errno);
232
233 foundVLVControl:
234         /* Create a BerElement from the berval returned in the control. */
235         ber = ber_init(&pControl->ldctl_value);
236
237         if (ber == NULL) {
238                 ld->ld_errno = LDAP_NO_MEMORY;
239                 return(ld->ld_errno);
240         }
241
242         /* Extract the data returned in the control. */
243         tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
244
245         if( tag == LBER_ERROR) {
246                 ber_free(ber, 1);
247                 ld->ld_errno = LDAP_DECODING_ERROR;
248                 return(ld->ld_errno);
249         }
250
251
252         /* Since the context is the last item encoded, if caller doesn't want
253            it returned, don't decode it. */
254         if (contextp) {
255                 if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
256                         tag = ber_scanf(ber, "tO", &berTag, contextp);
257
258                         if( tag == LBER_ERROR) {
259                                 ber_free(ber, 1);
260                                 ld->ld_errno = LDAP_DECODING_ERROR;
261                                 return(ld->ld_errno);
262                         }
263                 }
264         }
265
266         ber_free(ber, 1);
267
268         /* Return data to the caller for items that were requested. */
269         if (target_posp) {
270                 *target_posp = pos;
271         }
272         if (list_countp) {
273                 *list_countp = count;
274         }
275         if (errcodep) {
276                 *errcodep = err;
277         }
278
279         ld->ld_errno = LDAP_SUCCESS;
280         return(ld->ld_errno);
281 }