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