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