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