]> git.sur5r.net Git - openldap/blob - servers/slapd/back-relay/op.c
cleanup
[openldap] / servers / slapd / back-relay / op.c
1 /* op.c - relay backend operations */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2003-2004 The OpenLDAP Foundation.
5  * Portions Copyright 2004 Pierangelo Masarati.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Pierangelo Masarati for inclusion
18  * in OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include "slap.h"
26 #include "back-relay.h"
27
28 static int
29 relay_back_swap_bd( struct slap_op *op, struct slap_rep *rs )
30 {
31         slap_callback   *cb = op->o_callback;
32         BackendDB       *be = op->o_bd;
33
34         op->o_bd = cb->sc_private;
35         cb->sc_private = be;
36
37         return SLAP_CB_CONTINUE;
38 }
39
40 static BackendDB *
41 relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )
42 {
43         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
44         BackendDB               *bd = ri->ri_bd;
45
46         if ( bd == NULL ) {
47                 bd = select_backend( &op->o_req_ndn, 0, 1 );
48                 if ( bd == op->o_bd ) {
49                         if ( err != LDAP_SUCCESS ) {
50                                 send_ldap_error( op, rs,
51                                                 LDAP_UNWILLING_TO_PERFORM, 
52                                                 "would call self" );
53                         }
54                         return NULL;
55                 }
56         }
57
58         if ( bd == NULL ) {
59                 if ( default_referral ) {
60                         rs->sr_ref = referral_rewrite( default_referral,
61                                 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
62                         if ( !rs->sr_ref ) {
63                                 rs->sr_ref = default_referral;
64                         }
65
66                         rs->sr_err = LDAP_REFERRAL;
67                         send_ldap_result( op, rs );
68
69                         if ( rs->sr_ref != default_referral ) {
70                                 ber_bvarray_free( rs->sr_ref );
71                         }
72
73                 } else {
74                         /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
75                          * LDAP_NO_SUCH_OBJECT for other operations.
76                          * noSuchObject is not allowed to be returned by bind */
77                         rs->sr_err = err;
78                         send_ldap_result( op, rs );
79                 }
80         }
81
82         return bd;
83 }
84
85 int
86 relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )
87 {
88         BackendDB               *bd;
89         int                     rc = 1;
90
91         bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );
92         if ( bd == NULL ) {
93                 return rc;
94         }
95
96         if ( bd->be_bind ) {
97                 BackendDB       *be = op->o_bd;
98
99                 op->o_bd = bd;
100                 rc = ( bd->be_bind )( op, rs );
101                 op->o_bd = be;
102
103         } else {
104                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
105                                 "operation not supported "
106                                 "within naming context" );
107         }
108
109         return rc;
110 }
111
112 int
113 relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )
114 {
115         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
116         BackendDB               *bd;
117         int                     rc = 1;
118
119         bd = ri->ri_bd;
120         if ( bd == NULL ) {
121                 bd = select_backend( &op->o_req_ndn, 0, 1 );
122         }
123
124         if ( bd && bd->be_unbind ) {
125                 BackendDB       *be = op->o_bd;
126                 slap_callback   cb;
127
128                 cb.sc_next = op->o_callback;
129                 cb.sc_response = relay_back_swap_bd;
130                 cb.sc_cleanup = relay_back_swap_bd;
131                 cb.sc_private = op->o_bd;
132                 op->o_callback = &cb;
133
134                 op->o_bd = bd;
135                 rc = ( bd->be_unbind )( op, rs );
136                 op->o_bd = be;
137         }
138
139         return 0;
140
141 }
142
143 int
144 relay_back_op_search( struct slap_op *op, struct slap_rep *rs )
145 {
146         BackendDB               *bd;
147         int                     rc = 1;
148
149         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
150         if ( bd == NULL ) {
151                 return 1;
152         }
153
154         if ( bd->be_search ) {
155                 BackendDB       *be = op->o_bd;
156                 slap_callback   cb;
157
158                 cb.sc_next = op->o_callback;
159                 cb.sc_response = relay_back_swap_bd;
160                 cb.sc_cleanup = relay_back_swap_bd;
161                 cb.sc_private = op->o_bd;
162                 op->o_callback = &cb;
163
164                 op->o_bd = bd;
165                 rc = ( bd->be_search )( op, rs );
166                 op->o_bd = be;
167
168         } else {
169                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
170                                 "operation not supported "
171                                 "within naming context" );
172         }
173
174         return rc;
175
176 }
177
178 int
179 relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )
180 {
181         BackendDB               *bd;
182         int                     rc = 1;
183
184         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
185         if ( bd == NULL ) {
186                 return 1;
187         }
188
189         if ( bd->be_compare ) {
190                 BackendDB       *be = op->o_bd;
191                 slap_callback   cb;
192
193                 cb.sc_next = op->o_callback;
194                 cb.sc_response = relay_back_swap_bd;
195                 cb.sc_cleanup = relay_back_swap_bd;
196                 cb.sc_private = op->o_bd;
197                 op->o_callback = &cb;
198
199                 op->o_bd = bd;
200                 rc = ( bd->be_compare )( op, rs );
201                 op->o_bd = be;
202
203         } else {
204                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
205                                 "operation not supported "
206                                 "within naming context" );
207         }
208
209         return rc;
210
211 }
212
213 int
214 relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )
215 {
216         BackendDB               *bd;
217         int                     rc = 1;
218
219         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
220         if ( bd == NULL ) {
221                 return 1;
222         }
223
224         if ( bd->be_modify ) {
225                 BackendDB       *be = op->o_bd;
226                 slap_callback   cb;
227
228                 cb.sc_next = op->o_callback;
229                 cb.sc_response = relay_back_swap_bd;
230                 cb.sc_cleanup = relay_back_swap_bd;
231                 cb.sc_private = op->o_bd;
232                 op->o_callback = &cb;
233
234                 op->o_bd = bd;
235                 rc = ( bd->be_modify )( op, rs );
236                 op->o_bd = be;
237
238         } else {
239                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
240                                 "operation not supported "
241                                 "within naming context" );
242         }
243
244         return rc;
245
246 }
247
248 int
249 relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )
250 {
251         BackendDB               *bd;
252         int                     rc = 1;
253
254         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
255         if ( bd == NULL ) {
256                 return 1;
257         }
258
259         if ( bd->be_modrdn ) {
260                 BackendDB       *be = op->o_bd;
261                 slap_callback   cb;
262
263                 cb.sc_next = op->o_callback;
264                 cb.sc_response = relay_back_swap_bd;
265                 cb.sc_cleanup = relay_back_swap_bd;
266                 cb.sc_private = op->o_bd;
267                 op->o_callback = &cb;
268
269                 op->o_bd = bd;
270                 rc = ( bd->be_modrdn )( op, rs );
271                 op->o_bd = be;
272
273         } else {
274                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
275                                 "operation not supported "
276                                 "within naming context" );
277         }
278
279         return rc;
280
281 }
282
283 int
284 relay_back_op_add( struct slap_op *op, struct slap_rep *rs )
285 {
286         BackendDB               *bd;
287         int                     rc = 1;
288
289         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
290         if ( bd == NULL ) {
291                 return 1;
292         }
293
294         if ( bd->be_add ) {
295                 BackendDB       *be = op->o_bd;
296                 slap_callback   cb;
297
298                 cb.sc_next = op->o_callback;
299                 cb.sc_response = relay_back_swap_bd;
300                 cb.sc_cleanup = relay_back_swap_bd;
301                 cb.sc_private = op->o_bd;
302                 op->o_callback = &cb;
303
304                 op->o_bd = bd;
305                 rc = ( bd->be_add )( op, rs );
306                 op->o_bd = be;
307
308         } else {
309                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
310                                 "operation not supported "
311                                 "within naming context" );
312         }
313
314         return rc;
315
316 }
317
318 int
319 relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )
320 {
321         BackendDB               *bd;
322         int                     rc = 1;
323
324         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
325         if ( bd == NULL ) {
326                 return 1;
327         }
328
329         if ( bd->be_delete ) {
330                 BackendDB       *be = op->o_bd;
331                 slap_callback   cb;
332
333                 cb.sc_next = op->o_callback;
334                 cb.sc_response = relay_back_swap_bd;
335                 cb.sc_cleanup = relay_back_swap_bd;
336                 cb.sc_private = op->o_bd;
337                 op->o_callback = &cb;
338
339                 op->o_bd = bd;
340                 rc = ( bd->be_delete )( op, rs );
341                 op->o_bd = be;
342         }
343
344         return rc;
345
346 }
347
348 int
349 relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )
350 {
351         BackendDB               *bd;
352         int                     rc = 1;
353
354         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
355         if ( bd == NULL ) {
356                 return 1;
357         }
358
359         if ( bd->be_abandon ) {
360                 BackendDB       *be = op->o_bd;
361                 slap_callback   cb;
362
363                 cb.sc_next = op->o_callback;
364                 cb.sc_response = relay_back_swap_bd;
365                 cb.sc_cleanup = relay_back_swap_bd;
366                 cb.sc_private = op->o_bd;
367                 op->o_callback = &cb;
368
369                 op->o_bd = bd;
370                 rc = ( bd->be_abandon )( op, rs );
371                 op->o_bd = be;
372
373         } else {
374                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
375                                 "operation not supported "
376                                 "within naming context" );
377         }
378
379         return rc;
380
381 }
382
383 int
384 relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )
385 {
386         BackendDB               *bd;
387         int                     rc = 1;
388
389         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
390         if ( bd == NULL ) {
391                 return 1;
392         }
393
394         if ( bd->be_cancel ) {
395                 BackendDB       *be = op->o_bd;
396                 slap_callback   cb;
397
398                 cb.sc_next = op->o_callback;
399                 cb.sc_response = relay_back_swap_bd;
400                 cb.sc_cleanup = relay_back_swap_bd;
401                 cb.sc_private = op->o_bd;
402                 op->o_callback = &cb;
403
404                 op->o_bd = bd;
405                 rc = ( bd->be_cancel )( op, rs );
406                 op->o_bd = be;
407
408         } else {
409                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
410                                 "operation not supported "
411                                 "within naming context" );
412         }
413
414         return rc;
415
416 }
417
418 int
419 relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )
420 {
421         BackendDB               *bd;
422         int                     rc = 1;
423
424         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
425         if ( bd == NULL ) {
426                 return 1;
427         }
428
429         if ( bd->be_extended ) {
430                 BackendDB       *be = op->o_bd;
431                 slap_callback   cb;
432
433                 cb.sc_next = op->o_callback;
434                 cb.sc_response = relay_back_swap_bd;
435                 cb.sc_cleanup = relay_back_swap_bd;
436                 cb.sc_private = op->o_bd;
437                 op->o_callback = &cb;
438
439                 op->o_bd = bd;
440                 rc = ( bd->be_extended )( op, rs );
441                 op->o_bd = be;
442
443         } else {
444                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
445                                 "operation not supported "
446                                 "within naming context" );
447         }
448
449         return rc;
450
451 }
452
453 int
454 relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )
455 {
456         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
457         BackendDB               *bd;
458         int                     rc = 1;
459
460         bd = ri->ri_bd;
461         if ( bd == NULL) {
462                 bd = select_backend( &op->o_req_ndn, 0, 1 );
463                 if ( bd == NULL ) {
464                         return 1;
465                 }
466         }
467
468         if ( bd->be_release ) {
469                 BackendDB       *be = op->o_bd;
470
471                 op->o_bd = bd;
472                 rc = ( bd->be_release )( op, e, rw );
473                 op->o_bd = be;
474         }
475
476         return rc;
477
478 }
479
480 int
481 relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,
482         ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
483 {
484         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
485         BackendDB               *bd;
486         int                     rc = 1;
487
488         bd = ri->ri_bd;
489         if ( bd == NULL) {
490                 bd = select_backend( &op->o_req_ndn, 0, 1 );
491                 if ( bd == NULL ) {
492                         return 1;
493                 }
494         }
495
496         if ( bd->be_fetch ) {
497                 BackendDB       *be = op->o_bd;
498
499                 op->o_bd = bd;
500                 rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );
501                 op->o_bd = be;
502         }
503
504         return rc;
505
506 }
507
508 int
509 relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
510 {
511         BackendDB               *bd;
512         int                     rc = 0;
513
514         bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
515         if ( bd == NULL ) {
516                 return 0;
517         }
518
519         if ( bd->be_chk_referrals ) {
520                 BackendDB       *be = op->o_bd;
521                 slap_callback   cb;
522
523                 cb.sc_next = op->o_callback;
524                 cb.sc_response = relay_back_swap_bd;
525                 cb.sc_cleanup = relay_back_swap_bd;
526                 cb.sc_private = op->o_bd;
527                 op->o_callback = &cb;
528
529                 op->o_bd = bd;
530                 rc = ( bd->be_chk_referrals )( op, rs );
531                 op->o_bd = be;
532         }
533
534         return rc;
535
536 }
537
538 int
539 relay_back_operational( struct slap_op *op, struct slap_rep *rs, 
540                 int opattrs, Attribute **ap )
541 {
542         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
543         BackendDB               *bd;
544         int                     rc = 1;
545
546         bd = ri->ri_bd;
547         if ( bd == NULL) {
548                 bd = select_backend( &op->o_req_ndn, 0, 1 );
549                 if ( bd == NULL ) {
550                         return 1;
551                 }
552         }
553
554         if ( bd->be_operational ) {
555                 BackendDB       *be = op->o_bd;
556
557                 op->o_bd = bd;
558                 rc = ( bd->be_operational )( op, rs, opattrs, ap );
559                 op->o_bd = be;
560         }
561
562         return rc;
563
564 }
565
566 int
567 relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )
568 {
569         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
570         BackendDB               *bd;
571         int                     rc = 1;
572
573         bd = ri->ri_bd;
574         if ( bd == NULL) {
575                 bd = select_backend( &op->o_req_ndn, 0, 1 );
576                 if ( bd == NULL ) {
577                         return 1;
578                 }
579         }
580
581         if ( bd->be_has_subordinates ) {
582                 BackendDB       *be = op->o_bd;
583
584                 op->o_bd = bd;
585                 rc = ( bd->be_has_subordinates )( op, e, hasSubs );
586                 op->o_bd = be;
587         }
588
589         return rc;
590
591 }
592
593 int
594 relay_back_connection_init( BackendDB *bd, struct slap_conn *c )
595 {
596         relay_back_info         *ri = (relay_back_info *)bd->be_private;
597
598         bd = ri->ri_bd;
599         if ( bd == NULL ) {
600                 return 0;
601         }
602
603         if ( bd->be_connection_init ) {
604                 return ( bd->be_connection_init )( bd, c );
605         }
606
607         return 0;
608 }
609
610 int
611 relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )
612 {
613         relay_back_info         *ri = (relay_back_info *)bd->be_private;
614
615         bd = ri->ri_bd;
616         if ( bd == NULL) {
617                 return 0;
618         }
619
620         if ( bd->be_connection_destroy ) {
621                 return ( bd->be_connection_destroy )( bd, c );
622         }
623
624         return 0;
625
626 }
627
628 /*
629  * FIXME: must implement tools as well
630  */