]> git.sur5r.net Git - openldap/blob - servers/slapd/back-null/null.c
a8e251ef0637f4b69865d94e3d61b372fded6719
[openldap] / servers / slapd / back-null / null.c
1 /* null.c - the null backend */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2002-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 originally developed by Hallvard Furuseth for inclusion
18  * in OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24 #include <ac/string.h>
25
26 #include "slap.h"
27 #include "config.h"
28
29 struct null_info {
30         int     ni_bind_allowed;
31         ID      ni_nextid;
32 };
33
34 static ConfigDriver null_cf_gen;
35
36 static ConfigTable nullcfg[] = {
37         { "bind", "true|FALSE", 1, 2, 0, ARG_ON_OFF|ARG_MAGIC,
38                 null_cf_gen,
39                 "( OLcfgDbAt:8.1 NAME 'olcDbBindAllowed' "
40                 "DESC 'Allow binds to this database' "
41                 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
42         { NULL, NULL, 0, 0, 0, ARG_IGNORED,
43                 NULL, NULL, NULL, NULL }
44 };
45
46 static ConfigOCs nullocs[] = {
47         { "( OLcfgDbOc:8.1 "
48                 "NAME 'olcNullConfig' "
49                 "DESC 'Null backend ocnfiguration' "
50                 "SUP olcDatabaseConfig "
51                 "MAY ( olcDbBindAllowed ) )",
52                 Cft_Database, nullcfg },
53         { NULL, 0, NULL }
54 };
55
56
57 /* LDAP operations */
58
59 static int
60 null_back_bind( Operation *op, SlapReply *rs )
61 {
62         struct null_info *ni = (struct null_info *) op->o_bd->be_private;
63
64         if ( ni->ni_bind_allowed || be_isroot_pw( op ) ) {
65                 /* front end will send result on success (0) */
66                 return LDAP_SUCCESS;
67         }
68
69         rs->sr_err = LDAP_INVALID_CREDENTIALS;
70         send_ldap_result( op, rs );
71
72         return rs->sr_err;
73 }
74
75
76 static int
77 null_back_respond( Operation *op, SlapReply *rs, int rc )
78 {
79         LDAPControl ctrl[SLAP_MAX_RESPONSE_CONTROLS], *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
80         int c = 0;
81
82         BerElementBuffer        ps_berbuf;
83         BerElement              *ps_ber = NULL;
84         LDAPControl             **preread_ctrl = NULL,
85                                 **postread_ctrl = NULL;
86
87         rs->sr_err = LDAP_OTHER;
88
89         /* this comes first, as in case of assertion failure
90          * any further processing must stop */
91         if ( get_assert( op ) ) {
92                 rs->sr_err = LDAP_ASSERTION_FAILED;
93                 goto respond;
94         }
95
96         if ( op->o_preread ) {
97                 Entry           e = { 0 };
98
99                 switch ( op->o_tag ) {
100                 case LDAP_REQ_MODIFY:
101                 case LDAP_REQ_RENAME:
102                 case LDAP_REQ_DELETE:
103                         e.e_name = op->o_req_dn;
104                         e.e_nname = op->o_req_ndn;
105
106                         preread_ctrl = &ctrls[c];
107                         *preread_ctrl = NULL;
108
109                         if ( slap_read_controls( op, rs, &e,
110                                 &slap_pre_read_bv, preread_ctrl ) )
111                         {
112                                 preread_ctrl = NULL;
113
114                                 Debug( LDAP_DEBUG_TRACE,
115                                         "<=- null_back_respond: pre-read "
116                                         "failed!\n", 0, 0, 0 );
117
118                                 if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
119                                         /* FIXME: is it correct to abort
120                                          * operation if control fails? */
121                                         goto respond;
122                                 }
123
124                         } else {
125                                 c++;
126                         }
127                         break;
128                 }
129         }
130
131         if ( op->o_postread ) {
132                 Entry           e = { 0 };
133
134                 switch ( op->o_tag ) {
135                 case LDAP_REQ_ADD:
136                 case LDAP_REQ_MODIFY:
137                 case LDAP_REQ_RENAME:
138                         if ( op->o_tag == LDAP_REQ_ADD ) {
139                                 e.e_name = op->ora_e->e_name;
140                                 e.e_nname = op->ora_e->e_nname;
141
142                         } else {
143                                 e.e_name = op->o_req_dn;
144                                 e.e_nname = op->o_req_ndn;
145                         }
146
147                         postread_ctrl = &ctrls[c];
148                         *postread_ctrl = NULL;
149
150                         if ( slap_read_controls( op, rs, &e,
151                                 &slap_post_read_bv, postread_ctrl ) )
152                         {
153                                 postread_ctrl = NULL;
154
155                                 Debug( LDAP_DEBUG_TRACE,
156                                         "<=- null_back_respond: post-read "
157                                         "failed!\n", 0, 0, 0 );
158
159                                 if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
160                                         /* FIXME: is it correct to abort
161                                          * operation if control fails? */
162                                         goto respond;
163                                 }
164
165                         } else {
166                                 c++;
167                         }
168                         break;
169                 }
170         }
171
172         if ( op->o_noop ) {
173                 switch ( op->o_tag ) {
174                 case LDAP_REQ_ADD:
175                 case LDAP_REQ_MODIFY:
176                 case LDAP_REQ_RENAME:
177                 case LDAP_REQ_DELETE:
178                 case LDAP_REQ_EXTENDED:
179                         rc = LDAP_X_NO_OPERATION;
180                         break;
181                 }
182         }
183
184         if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
185                 struct berval           cookie = BER_BVC( "" );
186
187                 /* should not be here... */
188                 assert( op->o_tag == LDAP_REQ_SEARCH );
189
190                 ctrl[c].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
191                 ctrl[c].ldctl_iscritical = 0;
192
193                 ps_ber = (BerElement *)&ps_berbuf;
194                 ber_init2( ps_ber, NULL, LBER_USE_DER );
195
196                 /* return size of 0 -- no estimate */
197                 ber_printf( ps_ber, "{iO}", 0, &cookie ); 
198
199                 if ( ber_flatten2( ps_ber, &ctrl[c].ldctl_value, 0 ) == -1 ) {
200                         goto done;
201                 }
202                 
203                 ctrls[c] = &ctrl[c];
204                 c++;
205         }
206
207         /* terminate controls array */
208         ctrls[c] = NULL;
209         rs->sr_ctrls = ctrls;
210         rs->sr_err = rc;
211
212 respond:;
213         send_ldap_result( op, rs );
214         rs->sr_ctrls = NULL;
215
216 done:;
217         if ( ps_ber != NULL ) {
218                 (void) ber_free_buf( ps_ber );
219         }
220
221         if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
222                 slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
223                 slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
224         }
225
226         if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
227                 slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
228                 slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
229         }
230
231         return rs->sr_err;
232 }
233
234 /* add, delete, modify, modrdn, search */
235 static int
236 null_back_success( Operation *op, SlapReply *rs )
237 {
238         return null_back_respond( op, rs, LDAP_SUCCESS );
239 }
240
241 /* compare */
242 static int
243 null_back_false( Operation *op, SlapReply *rs )
244 {
245         return null_back_respond( op, rs, LDAP_COMPARE_FALSE );
246 }
247
248
249 /* for overlays */
250 static int
251 null_back_entry_get(
252         Operation *op,
253         struct berval *ndn,
254         ObjectClass *oc,
255         AttributeDescription *at,
256         int rw,
257         Entry **ent )
258 {
259         /* don't admit the object isn't there */
260         return oc || at ? LDAP_NO_SUCH_ATTRIBUTE : LDAP_BUSY;
261 }
262
263
264 /* Slap tools */
265
266 static int
267 null_tool_entry_open( BackendDB *be, int mode )
268 {
269         return 0;
270 }
271
272 static int
273 null_tool_entry_close( BackendDB *be )
274 {
275         assert( be != NULL );
276         return 0;
277 }
278
279 static ID
280 null_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
281 {
282         return NOID;
283 }
284
285 static ID
286 null_tool_entry_next( BackendDB *be )
287 {
288         return NOID;
289 }
290
291 static Entry *
292 null_tool_entry_get( BackendDB *be, ID id )
293 {
294         assert( slapMode & SLAP_TOOL_MODE );
295         return NULL;
296 }
297
298 static ID
299 null_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
300 {
301         assert( slapMode & SLAP_TOOL_MODE );
302         assert( text != NULL );
303         assert( text->bv_val != NULL );
304         assert( text->bv_val[0] == '\0' );      /* overconservative? */
305
306         e->e_id = ((struct null_info *) be->be_private)->ni_nextid++;
307         return e->e_id;
308 }
309
310
311 /* Setup */
312
313 static int
314 null_cf_gen( ConfigArgs *c )
315 {
316         struct null_info *ni = (struct null_info *) c->be->be_private;
317
318         if ( c->op == SLAP_CONFIG_EMIT ) {
319                 c->value_int = ni->ni_bind_allowed;
320                 return LDAP_SUCCESS;
321         } else if ( c->op == LDAP_MOD_DELETE ) {
322                 ni->ni_bind_allowed = 0;
323                 return LDAP_SUCCESS;
324         }
325
326         ni->ni_bind_allowed = c->value_int;
327         return LDAP_SUCCESS;
328 }
329
330 static int
331 null_back_db_init( BackendDB *be, ConfigReply *cr )
332 {
333         struct null_info *ni = ch_calloc( 1, sizeof(struct null_info) );
334         ni->ni_bind_allowed = 0;
335         ni->ni_nextid = 1;
336         be->be_private = ni;
337         be->be_cf_ocs = be->bd_info->bi_cf_ocs;
338         return 0;
339 }
340
341 static int
342 null_back_db_destroy( Backend *be, ConfigReply *cr )
343 {
344         free( be->be_private );
345         return 0;
346 }
347
348
349 int
350 null_back_initialize( BackendInfo *bi )
351 {
352         static char *controls[] = {
353                 LDAP_CONTROL_ASSERT,
354                 LDAP_CONTROL_MANAGEDSAIT,
355                 LDAP_CONTROL_NOOP,
356                 LDAP_CONTROL_PAGEDRESULTS,
357                 LDAP_CONTROL_SUBENTRIES,
358                 LDAP_CONTROL_PRE_READ,
359                 LDAP_CONTROL_POST_READ,
360                 LDAP_CONTROL_X_PERMISSIVE_MODIFY,
361                 NULL
362         };
363
364         Debug( LDAP_DEBUG_TRACE,
365                 "null_back_initialize: initialize null backend\n", 0, 0, 0 );
366
367         bi->bi_flags |=
368                 SLAP_BFLAG_INCREMENT |
369                 SLAP_BFLAG_SUBENTRIES |
370                 SLAP_BFLAG_ALIASES |
371                 SLAP_BFLAG_REFERRALS;
372
373         bi->bi_controls = controls;
374
375         bi->bi_open = 0;
376         bi->bi_close = 0;
377         bi->bi_config = 0;
378         bi->bi_destroy = 0;
379
380         bi->bi_db_init = null_back_db_init;
381         bi->bi_db_config = config_generic_wrapper;
382         bi->bi_db_open = 0;
383         bi->bi_db_close = 0;
384         bi->bi_db_destroy = null_back_db_destroy;
385
386         bi->bi_op_bind = null_back_bind;
387         bi->bi_op_unbind = 0;
388         bi->bi_op_search = null_back_success;
389         bi->bi_op_compare = null_back_false;
390         bi->bi_op_modify = null_back_success;
391         bi->bi_op_modrdn = null_back_success;
392         bi->bi_op_add = null_back_success;
393         bi->bi_op_delete = null_back_success;
394         bi->bi_op_abandon = 0;
395
396         bi->bi_extended = 0;
397
398         bi->bi_chk_referrals = 0;
399
400         bi->bi_connection_init = 0;
401         bi->bi_connection_destroy = 0;
402
403         bi->bi_entry_get_rw = null_back_entry_get;
404
405         bi->bi_tool_entry_open = null_tool_entry_open;
406         bi->bi_tool_entry_close = null_tool_entry_close;
407         bi->bi_tool_entry_first = backend_tool_entry_first;
408         bi->bi_tool_entry_first_x = null_tool_entry_first_x;
409         bi->bi_tool_entry_next = null_tool_entry_next;
410         bi->bi_tool_entry_get = null_tool_entry_get;
411         bi->bi_tool_entry_put = null_tool_entry_put;
412
413         bi->bi_cf_ocs = nullocs;
414         return config_register_schema( nullcfg, nullocs );
415 }
416
417 #if SLAPD_NULL == SLAPD_MOD_DYNAMIC
418
419 /* conditionally define the init_module() function */
420 SLAP_BACKEND_INIT_MODULE( null )
421
422 #endif /* SLAPD_NULL == SLAPD_MOD_DYNAMIC */