]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sock/config.c
As an overlay, always return SLAP_CB_CONTINUE
[openldap] / servers / slapd / back-sock / config.c
1 /* config.c - sock backend configuration file routine */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2007-2011 The OpenLDAP Foundation.
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 Brian Candler for inclusion
18  * in OpenLDAP Software. Dynamic config support by Howard Chu.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include <ac/string.h>
26 #include <ac/socket.h>
27
28 #include "slap.h"
29 #include "config.h"
30 #include "back-sock.h"
31
32 static ConfigDriver bs_cf_gen;
33 static int sock_over_setup();
34 static slap_response sock_over_response;
35
36 enum {
37         BS_EXT = 1
38 };
39
40 static ConfigTable bscfg[] = {
41         { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
42                 (void *)offsetof(struct sockinfo, si_sockpath),
43                 "( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' "
44                         "DESC 'Pathname for Unix domain socket' "
45                         "EQUALITY caseExactMatch "
46                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
47         { "extensions", "ext", 2, 0, 0, ARG_MAGIC|BS_EXT,
48                 bs_cf_gen, "( OLcfgDbAt:7.2 NAME 'olcDbSocketExtensions' "
49                         "DESC 'binddn, peername, or ssf' "
50                         "EQUALITY caseIgnoreMatch "
51                         "SYNTAX OMsDirectoryString )", NULL, NULL },
52         { NULL, NULL }
53 };
54
55 static ConfigOCs bsocs[] = {
56         { "( OLcfgDbOc:7.1 "
57                 "NAME 'olcDbSocketConfig' "
58                 "DESC 'Socket backend configuration' "
59                 "SUP olcDatabaseConfig "
60                 "MUST olcDbSocketPath "
61                 "MAY olcDbSocketExtensions )",
62                         Cft_Database, bscfg },
63         { NULL, 0, NULL }
64 };
65
66 static ConfigOCs osocs[] = {
67         { "( OLcfgOvOc:22.1 "
68                 "NAME 'olcOvSocketConfig' "
69                 "DESC 'Socket overlay configuration' "
70                 "SUP olcOverlayConfig "
71                 "MUST olcDbSocketPath "
72                 "MAY olcDbSocketExtensions )",
73                         Cft_Overlay, bscfg },
74         { NULL, 0, NULL }
75 };
76
77 static slap_verbmasks bs_exts[] = {
78         { BER_BVC("binddn"), SOCK_EXT_BINDDN },
79         { BER_BVC("peername"), SOCK_EXT_PEERNAME },
80         { BER_BVC("ssf"), SOCK_EXT_SSF },
81         { BER_BVC("connid"), SOCK_EXT_CONNID },
82         { BER_BVNULL, 0 }
83 };
84
85 static int
86 bs_cf_gen( ConfigArgs *c )
87 {
88         struct sockinfo *si;
89         int rc;
90
91         if ( c->be && c->table == Cft_Database )
92                 si = c->be->be_private;
93         else if ( c->bi )
94                 si = c->bi->bi_private;
95         else
96                 return ARG_BAD_CONF;
97
98         if ( c->op == SLAP_CONFIG_EMIT ) {
99                 switch( c->type ) {
100                 case BS_EXT:
101                         return mask_to_verbs( bs_exts, si->si_extensions, &c->rvalue_vals );
102                 }
103         } else if ( c->op == LDAP_MOD_DELETE ) {
104                 switch( c->type ) {
105                 case BS_EXT:
106                         if ( c->valx < 0 ) {
107                                 si->si_extensions = 0;
108                                 rc = 0;
109                         } else {
110                                 slap_mask_t dels = 0;
111                                 rc = verbs_to_mask( c->argc, c->argv, bs_exts, &dels );
112                                 if ( rc == 0 )
113                                         si->si_extensions ^= dels;
114                         }
115                         return rc;
116                 }
117
118         } else {
119                 switch( c->type ) {
120                 case BS_EXT:
121                         return verbs_to_mask( c->argc, c->argv, bs_exts, &si->si_extensions );
122                 }
123         }
124         return 1;
125 }
126
127 int
128 sock_back_init_cf( BackendInfo *bi )
129 {
130         int rc;
131         bi->bi_cf_ocs = bsocs;
132
133         rc = config_register_schema( bscfg, bsocs );
134         if ( !rc )
135                 rc = sock_over_setup();
136         return rc;
137 }
138
139 /* sock overlay wrapper */
140 static slap_overinst sockover;
141
142 static int sock_over_db_init( Backend *be, struct config_reply_s *cr );
143 static int sock_over_db_destroy( Backend *be, struct config_reply_s *cr );
144
145 static BI_op_bind *sockfuncs[] = {
146         sock_back_bind,
147         sock_back_unbind,
148         sock_back_search,
149         sock_back_compare,
150         sock_back_modify,
151         sock_back_modrdn,
152         sock_back_add,
153         sock_back_delete
154 };
155
156 static int sock_over_op(
157         Operation *op,
158         SlapReply *rs
159 )
160 {
161         slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
162         void *private = op->o_bd->be_private;
163         slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
164         slap_operation_t which;
165         int rc;
166
167         switch (op->o_tag) {
168         case LDAP_REQ_BIND:     which = op_bind; break;
169         case LDAP_REQ_UNBIND:   which = op_unbind; break;
170         case LDAP_REQ_SEARCH:   which = op_search; break;
171         case LDAP_REQ_COMPARE:  which = op_compare; break;
172         case LDAP_REQ_MODIFY:   which = op_modify; break;
173         case LDAP_REQ_MODRDN:   which = op_modrdn; break;
174         case LDAP_REQ_ADD:      which = op_add; break;
175         case LDAP_REQ_DELETE:   which = op_delete; break;
176         default:
177                 return SLAP_CB_CONTINUE;
178         }
179         op->o_bd->be_private = on->on_bi.bi_private;
180         cb.sc_next = op->o_callback;
181         op->o_callback = &cb;
182         rc = sockfuncs[which]( op, rs );
183         op->o_bd->be_private = private;
184         op->o_callback = cb.sc_next;
185         return SLAP_CB_CONTINUE;
186 }
187
188 static int
189 sock_over_response( Operation *op, SlapReply *rs )
190 {
191         slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
192         struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private;
193         FILE *fp;
194
195         if ( rs->sr_type != REP_RESULT )
196                 return SLAP_CB_CONTINUE;
197
198         if (( fp = opensock( si->si_sockpath )) == NULL )
199                 return SLAP_CB_CONTINUE;
200
201         /* write out the result */
202         fprintf( fp, "RESULT\n" );
203         fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
204         sock_print_conn( fp, op->o_conn, si );
205         fprintf( fp, "code: %d\n", rs->sr_err );
206         if ( rs->sr_matched )
207                 fprintf( fp, "matched: %s\n", rs->sr_matched );
208         if (rs->sr_text )
209                 fprintf( fp, "info: %s\n", rs->sr_text );
210         fprintf( fp, "\n" );
211         fclose( fp );
212
213         return SLAP_CB_CONTINUE;
214 }
215
216 static int
217 sock_over_setup()
218 {
219         int rc;
220
221         sockover.on_bi.bi_type = "sock";
222         sockover.on_bi.bi_db_init = sock_over_db_init;
223         sockover.on_bi.bi_db_destroy = sock_over_db_destroy;
224
225         sockover.on_bi.bi_op_bind = sock_over_op;
226         sockover.on_bi.bi_op_unbind = sock_over_op;
227         sockover.on_bi.bi_op_search = sock_over_op;
228         sockover.on_bi.bi_op_compare = sock_over_op;
229         sockover.on_bi.bi_op_modify = sock_over_op;
230         sockover.on_bi.bi_op_modrdn = sock_over_op;
231         sockover.on_bi.bi_op_add = sock_over_op;
232         sockover.on_bi.bi_op_delete = sock_over_op;
233         sockover.on_response = sock_over_response;
234
235         sockover.on_bi.bi_cf_ocs = osocs;
236
237         rc = config_register_schema( bscfg, osocs );
238         if ( rc ) return rc;
239
240         return overlay_register( &sockover );
241 }
242
243 static int
244 sock_over_db_init(
245     Backend     *be,
246         struct config_reply_s *cr
247 )
248 {
249         slap_overinst   *on = (slap_overinst *)be->bd_info;
250         void *private = be->be_private;
251         int rc;
252
253         be->be_private = NULL;
254         rc = sock_back_db_init( be, cr );
255         on->on_bi.bi_private = be->be_private;
256         be->be_private = private;
257         return rc;
258 }
259
260 static int
261 sock_over_db_destroy(
262     Backend     *be,
263         struct config_reply_s *cr
264 )
265 {
266         slap_overinst   *on = (slap_overinst *)be->bd_info;
267         void *private = be->be_private;
268         int rc;
269
270         be->be_private = on->on_bi.bi_private;
271         rc = sock_back_db_destroy( be, cr );
272         on->on_bi.bi_private = be->be_private;
273         be->be_private = private;
274         return rc;
275 }