Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/ldap/libldap/vlvctrl.c
4394 views
1
/* $OpenLDAP$ */
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
*
4
* Copyright 1998-2024 The OpenLDAP Foundation.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted only as authorized by the OpenLDAP
9
* Public License.
10
*
11
* A copy of this license is available in the file LICENSE in the
12
* top-level directory of the distribution or, alternatively, at
13
* <http://www.OpenLDAP.org/license.html>.
14
*/
15
/* Portions Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
16
*
17
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
18
* TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
19
* TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
20
* AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
21
* IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
22
* OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
23
* PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
24
* THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
25
*---
26
* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
27
* can be found in the file "build/LICENSE-2.0.1" in this distribution
28
* of OpenLDAP Software.
29
*/
30
31
#include "portable.h"
32
33
#include <stdio.h>
34
#include <ac/stdlib.h>
35
#include <ac/string.h>
36
#include <ac/time.h>
37
38
#include "ldap-int.h"
39
40
#define LDAP_VLVBYINDEX_IDENTIFIER 0xa0L
41
#define LDAP_VLVBYVALUE_IDENTIFIER 0x81L
42
#define LDAP_VLVCONTEXT_IDENTIFIER 0x04L
43
44
45
/*---
46
ldap_create_vlv_control
47
48
Create and encode the Virtual List View control.
49
50
ld (IN) An LDAP session handle.
51
52
vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
53
are used to construct the value of the control
54
that is created.
55
56
value (OUT) A struct berval that contains the value to be assigned to the ldctl_value member
57
of an LDAPControl structure that contains the
58
VirtualListViewRequest control.
59
The bv_val member of the berval structure
60
SHOULD be freed when it is no longer in use by
61
calling ldap_memfree().
62
63
64
Ber encoding
65
66
VirtualListViewRequest ::= SEQUENCE {
67
beforeCount INTEGER (0 .. maxInt),
68
afterCount INTEGER (0 .. maxInt),
69
CHOICE {
70
byoffset [0] SEQUENCE, {
71
offset INTEGER (0 .. maxInt),
72
contentCount INTEGER (0 .. maxInt) }
73
[1] greaterThanOrEqual assertionValue }
74
contextID OCTET STRING OPTIONAL }
75
76
77
Note: The first time the VLV control is created, the ldvlv_context
78
field of the LDAPVLVInfo structure should be set to NULL.
79
The context obtained from calling ldap_parse_vlv_control()
80
should be used as the context in the next ldap_create_vlv_control
81
call.
82
83
---*/
84
85
int
86
ldap_create_vlv_control_value(
87
LDAP *ld,
88
LDAPVLVInfo *vlvinfop,
89
struct berval *value )
90
{
91
ber_tag_t tag;
92
BerElement *ber;
93
94
if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
95
if ( ld )
96
ld->ld_errno = LDAP_PARAM_ERROR;
97
return LDAP_PARAM_ERROR;
98
}
99
100
assert( LDAP_VALID( ld ) );
101
102
value->bv_val = NULL;
103
value->bv_len = 0;
104
ld->ld_errno = LDAP_SUCCESS;
105
106
ber = ldap_alloc_ber_with_options( ld );
107
if ( ber == NULL ) {
108
ld->ld_errno = LDAP_NO_MEMORY;
109
return ld->ld_errno;
110
}
111
112
tag = ber_printf( ber, "{ii" /*}*/,
113
vlvinfop->ldvlv_before_count,
114
vlvinfop->ldvlv_after_count );
115
if ( tag == LBER_ERROR ) {
116
goto error_return;
117
}
118
119
if ( vlvinfop->ldvlv_attrvalue == NULL ) {
120
tag = ber_printf( ber, "t{iiN}",
121
LDAP_VLVBYINDEX_IDENTIFIER,
122
vlvinfop->ldvlv_offset,
123
vlvinfop->ldvlv_count );
124
if ( tag == LBER_ERROR ) {
125
goto error_return;
126
}
127
128
} else {
129
tag = ber_printf( ber, "tO",
130
LDAP_VLVBYVALUE_IDENTIFIER,
131
vlvinfop->ldvlv_attrvalue );
132
if ( tag == LBER_ERROR ) {
133
goto error_return;
134
}
135
}
136
137
if ( vlvinfop->ldvlv_context ) {
138
tag = ber_printf( ber, "tO",
139
LDAP_VLVCONTEXT_IDENTIFIER,
140
vlvinfop->ldvlv_context );
141
if ( tag == LBER_ERROR ) {
142
goto error_return;
143
}
144
}
145
146
tag = ber_printf( ber, /*{*/ "N}" );
147
if ( tag == LBER_ERROR ) {
148
goto error_return;
149
}
150
151
if ( ber_flatten2( ber, value, 1 ) == -1 ) {
152
ld->ld_errno = LDAP_NO_MEMORY;
153
}
154
155
if ( 0 ) {
156
error_return:;
157
ld->ld_errno = LDAP_ENCODING_ERROR;
158
}
159
160
if ( ber != NULL ) {
161
ber_free( ber, 1 );
162
}
163
164
return ld->ld_errno;
165
}
166
167
/*---
168
ldap_create_vlv_control
169
170
Create and encode the Virtual List View control.
171
172
ld (IN) An LDAP session handle.
173
174
vlvinfop (IN) The address of an LDAPVLVInfo structure whose contents
175
are used to construct the value of the control
176
that is created.
177
178
ctrlp (OUT) A result parameter that will be assigned the address
179
of an LDAPControl structure that contains the
180
VirtualListViewRequest control created by this function.
181
The memory occupied by the LDAPControl structure
182
SHOULD be freed when it is no longer in use by
183
calling ldap_control_free().
184
185
186
Ber encoding
187
188
VirtualListViewRequest ::= SEQUENCE {
189
beforeCount INTEGER (0 .. maxInt),
190
afterCount INTEGER (0 .. maxInt),
191
CHOICE {
192
byoffset [0] SEQUENCE, {
193
offset INTEGER (0 .. maxInt),
194
contentCount INTEGER (0 .. maxInt) }
195
[1] greaterThanOrEqual assertionValue }
196
contextID OCTET STRING OPTIONAL }
197
198
199
Note: The first time the VLV control is created, the ldvlv_context
200
field of the LDAPVLVInfo structure should be set to NULL.
201
The context obtained from calling ldap_parse_vlv_control()
202
should be used as the context in the next ldap_create_vlv_control
203
call.
204
205
---*/
206
207
int
208
ldap_create_vlv_control(
209
LDAP *ld,
210
LDAPVLVInfo *vlvinfop,
211
LDAPControl **ctrlp )
212
{
213
struct berval value;
214
215
if ( ctrlp == NULL ) {
216
ld->ld_errno = LDAP_PARAM_ERROR;
217
return ld->ld_errno;
218
}
219
220
ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
221
if ( ld->ld_errno == LDAP_SUCCESS ) {
222
223
ld->ld_errno = ldap_control_create( LDAP_CONTROL_VLVREQUEST,
224
1, &value, 0, ctrlp );
225
if ( ld->ld_errno != LDAP_SUCCESS ) {
226
LDAP_FREE( value.bv_val );
227
}
228
}
229
230
return ld->ld_errno;
231
}
232
233
234
/*---
235
ldap_parse_vlvresponse_control
236
237
Decode the Virtual List View control return information.
238
239
ld (IN) An LDAP session handle.
240
241
ctrl (IN) The address of the LDAPControl structure.
242
243
target_posp (OUT) This result parameter is filled in with the list
244
index of the target entry. If this parameter is
245
NULL, the target position is not returned.
246
247
list_countp (OUT) This result parameter is filled in with the server's
248
estimate of the size of the list. If this parameter
249
is NULL, the size is not returned.
250
251
contextp (OUT) This result parameter is filled in with the address
252
of a struct berval that contains the server-
253
generated context identifier if one was returned by
254
the server. If the server did not return a context
255
identifier, this parameter will be set to NULL, even
256
if an error occurred.
257
The returned context SHOULD be used in the next call
258
to create a VLV sort control. The struct berval
259
returned SHOULD be disposed of by calling ber_bvfree()
260
when it is no longer needed. If NULL is passed for
261
contextp, the context identifier is not returned.
262
263
errcodep (OUT) This result parameter is filled in with the VLV
264
result code. If this parameter is NULL, the result
265
code is not returned.
266
267
268
Ber encoding
269
270
VirtualListViewResponse ::= SEQUENCE {
271
targetPosition INTEGER (0 .. maxInt),
272
contentCount INTEGER (0 .. maxInt),
273
virtualListViewResult ENUMERATED {
274
success (0),
275
operationsError (1),
276
unwillingToPerform (53),
277
insufficientAccessRights (50),
278
busy (51),
279
timeLimitExceeded (3),
280
adminLimitExceeded (11),
281
sortControlMissing (60),
282
offsetRangeError (61),
283
other (80) },
284
contextID OCTET STRING OPTIONAL }
285
286
---*/
287
288
int
289
ldap_parse_vlvresponse_control(
290
LDAP *ld,
291
LDAPControl *ctrl,
292
ber_int_t *target_posp,
293
ber_int_t *list_countp,
294
struct berval **contextp,
295
ber_int_t *errcodep )
296
{
297
BerElement *ber;
298
ber_int_t pos, count, err;
299
ber_tag_t tag, berTag;
300
ber_len_t berLen;
301
302
assert( ld != NULL );
303
assert( LDAP_VALID( ld ) );
304
305
if (contextp) {
306
*contextp = NULL; /* Make sure we return a NULL if error occurs. */
307
}
308
309
if (ctrl == NULL) {
310
ld->ld_errno = LDAP_PARAM_ERROR;
311
return(ld->ld_errno);
312
}
313
314
if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
315
/* Not VLV Response control */
316
ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
317
return(ld->ld_errno);
318
}
319
320
/* Create a BerElement from the berval returned in the control. */
321
ber = ber_init(&ctrl->ldctl_value);
322
323
if (ber == NULL) {
324
ld->ld_errno = LDAP_NO_MEMORY;
325
return(ld->ld_errno);
326
}
327
328
/* Extract the data returned in the control. */
329
tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
330
331
if( tag == LBER_ERROR) {
332
ber_free(ber, 1);
333
ld->ld_errno = LDAP_DECODING_ERROR;
334
return(ld->ld_errno);
335
}
336
337
338
/* Since the context is the last item encoded, if caller doesn't want
339
it returned, don't decode it. */
340
if (contextp) {
341
if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
342
tag = ber_scanf(ber, "tO", &berTag, contextp);
343
344
if( tag == LBER_ERROR) {
345
ber_free(ber, 1);
346
ld->ld_errno = LDAP_DECODING_ERROR;
347
return(ld->ld_errno);
348
}
349
}
350
}
351
352
ber_free(ber, 1);
353
354
/* Return data to the caller for items that were requested. */
355
if (target_posp) *target_posp = pos;
356
if (list_countp) *list_countp = count;
357
if (errcodep) *errcodep = err;
358
359
ld->ld_errno = LDAP_SUCCESS;
360
return(ld->ld_errno);
361
}
362
363