]> git.sur5r.net Git - openldap/blob - servers/slapd/back-relay/init.c
bbf2839d2407d0913199f3008529076744d00a39
[openldap] / servers / slapd / back-relay / init.c
1 /* init.c - initialize relay backend */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2004-2015 The OpenLDAP Foundation.
6  * Portions Copyright 2004 Pierangelo Masarati.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Pierangelo Masarati for inclusion
19  * in OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include <ac/string.h>
26
27 #include "slap.h"
28 #include "config.h"
29 #include "back-relay.h"
30
31 static ConfigDriver relay_back_cf;
32
33 static ConfigTable relaycfg[] = {
34         { "relay", "relay", 2, 2, 0,
35                 ARG_MAGIC|ARG_DN,
36                 relay_back_cf, "( OLcfgDbAt:5.1 "
37                         "NAME 'olcRelay' "
38                         "DESC 'Relay DN' "
39                         "SYNTAX OMsDN "
40                         "SINGLE-VALUE )",
41                 NULL, NULL },
42         { NULL }
43 };
44
45 static ConfigOCs relayocs[] = {
46         { "( OLcfgDbOc:5.1 "
47                 "NAME 'olcRelayConfig' "
48                 "DESC 'Relay backend configuration' "
49                 "SUP olcDatabaseConfig "
50                 "MAY ( olcRelay "
51                 ") )",
52                         Cft_Database, relaycfg},
53         { NULL, 0, NULL }
54 };
55
56 static int
57 relay_back_cf( ConfigArgs *c )
58 {
59         relay_back_info *ri = ( relay_back_info * )c->be->be_private;
60         int             rc = 0;
61
62         if ( c->op == SLAP_CONFIG_EMIT ) {
63                 if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) {
64                         value_add_one( &c->rvalue_vals, &ri->ri_realsuffix );
65                         return 0;
66                 }
67                 return 1;
68
69         } else if ( c->op == LDAP_MOD_DELETE ) {
70                 if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
71                         ch_free( ri->ri_realsuffix.bv_val );
72                         BER_BVZERO( &ri->ri_realsuffix );
73                         ri->ri_bd = NULL;
74                         return 0;
75                 }
76                 return 1;
77
78         } else {
79                 BackendDB *bd;
80
81                 assert( ri != NULL );
82                 assert( BER_BVISNULL( &ri->ri_realsuffix ) );
83
84                 if ( c->be->be_nsuffix == NULL ) {
85                         snprintf( c->cr_msg, sizeof( c->cr_msg),
86                                 "\"relay\" directive "
87                                 "must appear after \"suffix\"" );
88                         Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
89                                 "%s: %s.\n", c->log, c->cr_msg );
90                         rc = 1;
91                         goto relay_done;
92                 }
93
94                 if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) {
95                         snprintf( c->cr_msg, sizeof( c->cr_msg),
96                                 "relaying of multiple suffix "
97                                 "database not supported" );
98                         Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
99                                 "%s: %s.\n", c->log, c->cr_msg );
100                         rc = 1;
101                         goto relay_done;
102                 }
103
104                 bd = select_backend( &c->value_ndn, 1 );
105                 if ( bd == NULL ) {
106                         snprintf( c->cr_msg, sizeof( c->cr_msg),
107                                 "cannot find database "
108                                 "of relay dn \"%s\" "
109                                 "in \"olcRelay <dn>\"\n",
110                                 c->value_dn.bv_val );
111                         Log2( LDAP_DEBUG_CONFIG, LDAP_LEVEL_ERR,
112                                 "%s: %s.\n", c->log, c->cr_msg );
113
114                 } else if ( bd->be_private == c->be->be_private ) {
115                         snprintf( c->cr_msg, sizeof( c->cr_msg),
116                                 "relay dn \"%s\" would call self "
117                                 "in \"relay <dn>\" line\n",
118                                 c->value_dn.bv_val );
119                         Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
120                                 "%s: %s.\n", c->log, c->cr_msg );
121                         rc = 1;
122                         goto relay_done;
123                 }
124
125                 ri->ri_realsuffix = c->value_ndn;
126                 BER_BVZERO( &c->value_ndn );
127
128 relay_done:;
129                 ch_free( c->value_dn.bv_val );
130                 ch_free( c->value_ndn.bv_val );
131         }
132
133         return rc;
134 }
135
136 int
137 relay_back_initialize( BackendInfo *bi )
138 {
139         bi->bi_init = 0;
140         bi->bi_open = 0;
141         bi->bi_config = 0;
142         bi->bi_close = 0;
143         bi->bi_destroy = 0;
144
145         bi->bi_db_init = relay_back_db_init;
146         bi->bi_db_config = config_generic_wrapper;
147         bi->bi_db_open = relay_back_db_open;
148 #if 0
149         bi->bi_db_close = relay_back_db_close;
150 #endif
151         bi->bi_db_destroy = relay_back_db_destroy;
152
153         bi->bi_op_bind = relay_back_op_bind;
154         bi->bi_op_search = relay_back_op_search;
155         bi->bi_op_compare = relay_back_op_compare;
156         bi->bi_op_modify = relay_back_op_modify;
157         bi->bi_op_modrdn = relay_back_op_modrdn;
158         bi->bi_op_add = relay_back_op_add;
159         bi->bi_op_delete = relay_back_op_delete;
160         bi->bi_extended = relay_back_op_extended;
161         bi->bi_entry_release_rw = relay_back_entry_release_rw;
162         bi->bi_entry_get_rw = relay_back_entry_get_rw;
163         bi->bi_operational = relay_back_operational;
164         bi->bi_has_subordinates = relay_back_has_subordinates;
165
166         bi->bi_cf_ocs = relayocs;
167
168         return config_register_schema( relaycfg, relayocs );
169 }
170
171 int
172 relay_back_db_init( Backend *be, ConfigReply *cr)
173 {
174         relay_back_info         *ri;
175
176         be->be_private = NULL;
177
178         ri = (relay_back_info *) ch_calloc( 1, RELAY_INFO_SIZE );
179         if ( ri == NULL ) {
180                 return -1;
181         }
182
183         ri->ri_bd = NULL;
184         BER_BVZERO( &ri->ri_realsuffix );
185         ri->ri_massage = 0;
186
187         be->be_cf_ocs = be->bd_info->bi_cf_ocs;
188
189         be->be_private = (void *)ri;
190
191         return 0;
192 }
193
194 int
195 relay_back_db_open( Backend *be, ConfigReply *cr )
196 {
197         relay_back_info         *ri = (relay_back_info *)be->be_private;
198
199         assert( ri != NULL );
200
201         if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
202                 ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 );
203
204                 /* must be there: it was during config! */
205                 if ( ri->ri_bd == NULL ) {
206                         snprintf( cr->msg, sizeof( cr->msg),
207                                 "cannot find database "
208                                 "of relay dn \"%s\" "
209                                 "in \"olcRelay <dn>\"\n",
210                                 ri->ri_realsuffix.bv_val );
211                         Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
212                                 "relay_back_db_open: %s.\n", cr->msg );
213
214                         return 1;
215                 }
216
217                 /* inherit controls */
218                 AC_MEMCPY( be->bd_self->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) );
219
220         } else {
221                 /* inherit all? */
222                 AC_MEMCPY( be->bd_self->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) );
223         }
224
225         return 0;
226 }
227
228 int
229 relay_back_db_close( Backend *be, ConfigReply *cr )
230 {
231         return 0;
232 }
233
234 int
235 relay_back_db_destroy( Backend *be, ConfigReply *cr)
236 {
237         relay_back_info         *ri = (relay_back_info *)be->be_private;
238
239         if ( ri ) {
240                 if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
241                         ch_free( ri->ri_realsuffix.bv_val );
242                 }
243                 ch_free( ri );
244         }
245
246         return 0;
247 }
248
249 #if SLAPD_RELAY == SLAPD_MOD_DYNAMIC
250
251 /* conditionally define the init_module() function */
252 SLAP_BACKEND_INIT_MODULE( relay )
253
254 #endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */