]> git.sur5r.net Git - openldap/blob - libraries/libldap/extended.c
Fix month field
[openldap] / libraries / libldap / extended.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 /*
8  * LDAPv3 Extended Operation Request
9  *      ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
10  *              requestName      [0] LDAPOID,
11  *              requestValue     [1] OCTET STRING OPTIONAL
12  *      }
13  *
14  * LDAPv3 Extended Operation Response
15  *      ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
16  *              COMPONENTS OF LDAPResult,
17  *              responseName     [10] LDAPOID OPTIONAL,
18  *              response         [11] OCTET STRING OPTIONAL
19  *      }
20  *
21  */
22
23 #include "portable.h"
24
25 #include <stdio.h>
26 #include <ac/stdlib.h>
27
28 #include <ac/socket.h>
29 #include <ac/string.h>
30 #include <ac/time.h>
31
32 #include "ldap-int.h"
33 #include "ldap_log.h"
34
35 int
36 ldap_extended_operation(
37         LDAP                    *ld,
38         LDAP_CONST char *reqoid,
39         struct berval   *reqdata,
40         LDAPControl             **sctrls,
41         LDAPControl             **cctrls,
42         int                             *msgidp )
43 {
44         BerElement *ber;
45         int rc;
46
47 #ifdef NEW_LOGGING
48         LDAP_LOG ( OPERATION, ENTRY, "ldap_extended_operation\n", 0,0,0 );
49 #else
50         Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 );
51 #endif
52
53         assert( ld != NULL );
54         assert( LDAP_VALID( ld ) );
55         assert( reqoid != NULL || *reqoid == '\0' );
56         assert( msgidp != NULL );
57
58         /* must be version 3 (or greater) */
59         if ( ld->ld_version < LDAP_VERSION3 ) {
60                 ld->ld_errno = LDAP_NOT_SUPPORTED;
61                 return( ld->ld_errno );
62         }
63
64         /* create a message to send */
65         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
66                 ld->ld_errno = LDAP_NO_MEMORY;
67                 return( ld->ld_errno );
68         }
69
70         if ( reqdata != NULL ) {
71                 rc = ber_printf( ber, "{it{tstON}", /* '}' */
72                         ++ld->ld_msgid, LDAP_REQ_EXTENDED,
73                         LDAP_TAG_EXOP_REQ_OID, reqoid,
74                         LDAP_TAG_EXOP_REQ_VALUE, reqdata );
75
76         } else {
77                 rc = ber_printf( ber, "{it{tsN}", /* '}' */
78                         ++ld->ld_msgid, LDAP_REQ_EXTENDED,
79                         LDAP_TAG_EXOP_REQ_OID, reqoid );
80         }
81
82         if( rc == -1 ) {
83                 ld->ld_errno = LDAP_ENCODING_ERROR;
84                 ber_free( ber, 1 );
85                 return( ld->ld_errno );
86         }
87
88         /* Put Server Controls */
89         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
90                 ber_free( ber, 1 );
91                 return ld->ld_errno;
92         }
93
94         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
95                 ld->ld_errno = LDAP_ENCODING_ERROR;
96                 ber_free( ber, 1 );
97                 return( ld->ld_errno );
98         }
99
100         /* send the message */
101         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber );
102
103         return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
104 }
105
106 int
107 ldap_extended_operation_s(
108         LDAP                    *ld,
109         LDAP_CONST char *reqoid,
110         struct berval   *reqdata,
111         LDAPControl             **sctrls,
112         LDAPControl             **cctrls,
113         char                    **retoidp,
114         struct berval   **retdatap )
115 {
116     int     rc;
117     int     msgid;
118     LDAPMessage *res;
119
120 #ifdef NEW_LOGGING
121         LDAP_LOG ( OPERATION, ENTRY, "ldap_extended_operation_s\n", 0,0,0 );
122 #else
123         Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation_s\n", 0, 0, 0 );
124 #endif
125
126         assert( ld != NULL );
127         assert( LDAP_VALID( ld ) );
128         assert( reqoid != NULL || *reqoid == '\0' );
129         assert( retoidp != NULL || retdatap != NULL );
130
131     rc = ldap_extended_operation( ld, reqoid, reqdata,
132                 sctrls, cctrls, &msgid );
133         
134     if ( rc != LDAP_SUCCESS ) {
135         return( rc );
136         }
137  
138     if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
139         return( ld->ld_errno );
140         }
141
142         if ( retoidp != NULL ) *retoidp = NULL;
143         if ( retdatap != NULL ) *retdatap = NULL;
144
145         rc = ldap_parse_extended_result( ld, res, retoidp, retdatap, 0 );
146
147         if( rc != LDAP_SUCCESS ) {
148                 ldap_msgfree( res );
149                 return rc;
150         }
151
152     return( ldap_result2error( ld, res, 1 ) );
153 }
154
155 /* Parse an extended result */
156 int
157 ldap_parse_extended_result (
158         LDAP                    *ld,
159         LDAPMessage             *res,
160         char                    **retoidp,
161         struct berval   **retdatap,
162         int                             freeit )
163 {
164         BerElement *ber;
165         ber_tag_t rc;
166         ber_tag_t tag;
167         ber_len_t len;
168         struct berval *resdata;
169         ber_int_t errcode;
170         char *resoid;
171
172         assert( ld != NULL );
173         assert( LDAP_VALID( ld ) );
174         assert( res != NULL );
175
176 #ifdef NEW_LOGGING
177         LDAP_LOG ( OPERATION, ENTRY, "ldap_parse_extended_result\n", 0,0,0 );
178 #else
179         Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 );
180 #endif
181
182         if( ld->ld_version < LDAP_VERSION3 ) {
183                 ld->ld_errno = LDAP_NOT_SUPPORTED;
184                 return ld->ld_errno;
185         }
186
187         if( res->lm_msgtype != LDAP_RES_EXTENDED ) {
188                 ld->ld_errno = LDAP_PARAM_ERROR;
189                 return ld->ld_errno;
190         }
191
192         if( retoidp != NULL ) *retoidp = NULL;
193         if( retdatap != NULL ) *retdatap = NULL;
194
195         if ( ld->ld_error ) {
196                 LDAP_FREE( ld->ld_error );
197                 ld->ld_error = NULL;
198         }
199
200         if ( ld->ld_matched ) {
201                 LDAP_FREE( ld->ld_matched );
202                 ld->ld_matched = NULL;
203         }
204
205         ber = ber_dup( res->lm_ber );
206
207         if ( ber == NULL ) {
208                 ld->ld_errno = LDAP_NO_MEMORY;
209                 return ld->ld_errno;
210         }
211
212         rc = ber_scanf( ber, "{iaa" /*}*/, &errcode,
213                 &ld->ld_matched, &ld->ld_error );
214
215         if( rc == LBER_ERROR ) {
216                 ld->ld_errno = LDAP_DECODING_ERROR;
217                 ber_free( ber, 0 );
218                 return ld->ld_errno;
219         }
220
221         resoid = NULL;
222         resdata = NULL;
223
224         tag = ber_peek_tag( ber, &len );
225
226         if( tag == LDAP_TAG_REFERRAL ) {
227                 /* skip over referral */
228                 if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
229                         ld->ld_errno = LDAP_DECODING_ERROR;
230                         ber_free( ber, 0 );
231                         return ld->ld_errno;
232                 }
233
234                 tag = ber_peek_tag( ber, &len );
235         }
236
237         if( tag == LDAP_TAG_EXOP_RES_OID ) {
238                 /* we have a resoid */
239                 if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
240                         ld->ld_errno = LDAP_DECODING_ERROR;
241                         ber_free( ber, 0 );
242                         return ld->ld_errno;
243                 }
244
245                 tag = ber_peek_tag( ber, &len );
246         }
247
248         if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
249                 /* we have a resdata */
250                 if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
251                         ld->ld_errno = LDAP_DECODING_ERROR;
252                         ber_free( ber, 0 );
253                         if( resoid != NULL ) LDAP_FREE( resoid );
254                         return ld->ld_errno;
255                 }
256         }
257
258         ber_free( ber, 0 );
259
260         if( retoidp != NULL ) {
261                 *retoidp = resoid;
262         } else {
263                 LDAP_FREE( resoid );
264         }
265
266         if( retdatap != NULL ) {
267                 *retdatap = resdata;
268         } else {
269                 ber_bvfree( resdata );
270         }
271
272         ld->ld_errno = errcode;
273
274         if( freeit ) {
275                 ldap_msgfree( res );
276         }
277
278         return LDAP_SUCCESS;
279 }
280
281
282 /* Parse an extended partial */
283 int
284 ldap_parse_extended_partial (
285         LDAP                    *ld,
286         LDAPMessage             *res,
287         char                    **retoidp,
288         struct berval   **retdatap,
289         LDAPControl             ***serverctrls,
290         int                             freeit )
291 {
292         BerElement *ber;
293         ber_tag_t rc;
294         ber_tag_t tag;
295         ber_len_t len;
296         struct berval *resdata;
297         char *resoid;
298
299         assert( ld != NULL );
300         assert( LDAP_VALID( ld ) );
301         assert( res != NULL );
302
303 #ifdef NEW_LOGGING
304         LDAP_LOG ( OPERATION, ENTRY, "ldap_parse_extended_partial\n", 0,0,0 );
305 #else
306         Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_partial\n", 0, 0, 0 );
307 #endif
308
309         if( ld->ld_version < LDAP_VERSION3 ) {
310                 ld->ld_errno = LDAP_NOT_SUPPORTED;
311                 return ld->ld_errno;
312         }
313
314         if( res->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL ) {
315                 ld->ld_errno = LDAP_PARAM_ERROR;
316                 return ld->ld_errno;
317         }
318
319         if( retoidp != NULL ) *retoidp = NULL;
320         if( retdatap != NULL ) *retdatap = NULL;
321
322         ber = ber_dup( res->lm_ber );
323
324         if ( ber == NULL ) {
325                 ld->ld_errno = LDAP_NO_MEMORY;
326                 return ld->ld_errno;
327         }
328
329         rc = ber_scanf( ber, "{" /*}*/ );
330
331         if( rc == LBER_ERROR ) {
332                 ld->ld_errno = LDAP_DECODING_ERROR;
333                 ber_free( ber, 0 );
334                 return ld->ld_errno;
335         }
336
337         resoid = NULL;
338         resdata = NULL;
339
340         tag = ber_peek_tag( ber, &len );
341
342         if( tag == LDAP_TAG_EXOP_RES_OID ) {
343                 /* we have a resoid */
344                 if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
345                         ld->ld_errno = LDAP_DECODING_ERROR;
346                         ber_free( ber, 0 );
347                         return ld->ld_errno;
348                 }
349
350                 tag = ber_peek_tag( ber, &len );
351         }
352
353         if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
354                 /* we have a resdata */
355                 if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
356                         ld->ld_errno = LDAP_DECODING_ERROR;
357                         ber_free( ber, 0 );
358                         if( resoid != NULL ) LDAP_FREE( resoid );
359                         return ld->ld_errno;
360                 }
361         }
362
363         if ( serverctrls == NULL ) {
364                 rc = LDAP_SUCCESS;
365                 goto free_and_return;
366         }
367
368         if ( ber_scanf( ber, /*{*/ "}" ) == LBER_ERROR ) {
369                 rc = LDAP_DECODING_ERROR;
370                 goto free_and_return;
371         }
372
373         rc = ldap_int_get_controls( ber, serverctrls );
374
375 free_and_return:
376         ber_free( ber, 0 );
377
378         if( retoidp != NULL ) {
379                 *retoidp = resoid;
380         } else {
381                 LDAP_FREE( resoid );
382         }
383
384         if( retdatap != NULL ) {
385                 *retdatap = resdata;
386         } else {
387                 ber_bvfree( resdata );
388         }
389
390         if( freeit ) {
391                 ldap_msgfree( res );
392         }
393
394         return LDAP_SUCCESS;
395 }