Back to index

openldap  2.4.31
null.c
Go to the documentation of this file.
00001 /* null.c - the null backend */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2002-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was originally developed by Hallvard Furuseth for inclusion
00018  * in OpenLDAP Software.
00019  */
00020 
00021 #include "portable.h"
00022 
00023 #include <stdio.h>
00024 #include <ac/string.h>
00025 
00026 #include "slap.h"
00027 #include "config.h"
00028 
00029 struct null_info {
00030        int    ni_bind_allowed;
00031        ID     ni_nextid;
00032 };
00033 
00034 static ConfigDriver null_cf_gen;
00035 
00036 static ConfigTable nullcfg[] = {
00037        { "bind", "true|FALSE", 1, 2, 0, ARG_ON_OFF|ARG_MAGIC,
00038               null_cf_gen,
00039               "( OLcfgDbAt:8.1 NAME 'olcDbBindAllowed' "
00040               "DESC 'Allow binds to this database' "
00041               "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
00042        { NULL, NULL, 0, 0, 0, ARG_IGNORED,
00043               NULL, NULL, NULL, NULL }
00044 };
00045 
00046 static ConfigOCs nullocs[] = {
00047        { "( OLcfgDbOc:8.1 "
00048               "NAME 'olcNullConfig' "
00049               "DESC 'Null backend ocnfiguration' "
00050               "SUP olcDatabaseConfig "
00051               "MAY ( olcDbBindAllowed ) )",
00052               Cft_Database, nullcfg },
00053        { NULL, 0, NULL }
00054 };
00055 
00056 
00057 /* LDAP operations */
00058 
00059 static int
00060 null_back_bind( Operation *op, SlapReply *rs )
00061 {
00062        struct null_info *ni = (struct null_info *) op->o_bd->be_private;
00063 
00064        if ( ni->ni_bind_allowed || be_isroot_pw( op ) ) {
00065               /* front end will send result on success (0) */
00066               return LDAP_SUCCESS;
00067        }
00068 
00069        rs->sr_err = LDAP_INVALID_CREDENTIALS;
00070        send_ldap_result( op, rs );
00071 
00072        return rs->sr_err;
00073 }
00074 
00075 
00076 static int
00077 null_back_respond( Operation *op, SlapReply *rs, int rc )
00078 {
00079        LDAPControl ctrl[SLAP_MAX_RESPONSE_CONTROLS], *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
00080        int c = 0;
00081 
00082        BerElementBuffer     ps_berbuf;
00083        BerElement           *ps_ber = NULL;
00084        LDAPControl          **preread_ctrl = NULL,
00085                             **postread_ctrl = NULL;
00086 
00087        rs->sr_err = LDAP_OTHER;
00088 
00089        /* this comes first, as in case of assertion failure
00090         * any further processing must stop */
00091        if ( get_assert( op ) ) {
00092               rs->sr_err = LDAP_ASSERTION_FAILED;
00093               goto respond;
00094        }
00095 
00096        if ( op->o_preread ) {
00097               Entry         e = { 0 };
00098 
00099               switch ( op->o_tag ) {
00100               case LDAP_REQ_MODIFY:
00101               case LDAP_REQ_RENAME:
00102               case LDAP_REQ_DELETE:
00103                      e.e_name = op->o_req_dn;
00104                      e.e_nname = op->o_req_ndn;
00105 
00106                      preread_ctrl = &ctrls[c];
00107                      *preread_ctrl = NULL;
00108 
00109                      if ( slap_read_controls( op, rs, &e,
00110                             &slap_pre_read_bv, preread_ctrl ) )
00111                      {
00112                             preread_ctrl = NULL;
00113 
00114                             Debug( LDAP_DEBUG_TRACE,
00115                                    "<=- null_back_respond: pre-read "
00116                                    "failed!\n", 0, 0, 0 );
00117 
00118                             if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
00119                                    /* FIXME: is it correct to abort
00120                                     * operation if control fails? */
00121                                    goto respond;
00122                             }
00123 
00124                      } else {
00125                             c++;
00126                      }
00127                      break;
00128               }
00129        }
00130 
00131        if ( op->o_postread ) {
00132               Entry         e = { 0 };
00133 
00134               switch ( op->o_tag ) {
00135               case LDAP_REQ_ADD:
00136               case LDAP_REQ_MODIFY:
00137               case LDAP_REQ_RENAME:
00138                      if ( op->o_tag == LDAP_REQ_ADD ) {
00139                             e.e_name = op->ora_e->e_name;
00140                             e.e_nname = op->ora_e->e_nname;
00141 
00142                      } else {
00143                             e.e_name = op->o_req_dn;
00144                             e.e_nname = op->o_req_ndn;
00145                      }
00146 
00147                      postread_ctrl = &ctrls[c];
00148                      *postread_ctrl = NULL;
00149 
00150                      if ( slap_read_controls( op, rs, &e,
00151                             &slap_post_read_bv, postread_ctrl ) )
00152                      {
00153                             postread_ctrl = NULL;
00154 
00155                             Debug( LDAP_DEBUG_TRACE,
00156                                    "<=- null_back_respond: post-read "
00157                                    "failed!\n", 0, 0, 0 );
00158 
00159                             if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
00160                                    /* FIXME: is it correct to abort
00161                                     * operation if control fails? */
00162                                    goto respond;
00163                             }
00164 
00165                      } else {
00166                             c++;
00167                      }
00168                      break;
00169               }
00170        }
00171 
00172        if ( op->o_noop ) {
00173               switch ( op->o_tag ) {
00174               case LDAP_REQ_ADD:
00175               case LDAP_REQ_MODIFY:
00176               case LDAP_REQ_RENAME:
00177               case LDAP_REQ_DELETE:
00178               case LDAP_REQ_EXTENDED:
00179                      rc = LDAP_X_NO_OPERATION;
00180                      break;
00181               }
00182        }
00183 
00184        if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
00185               struct berval        cookie = BER_BVC( "" );
00186 
00187               /* should not be here... */
00188               assert( op->o_tag == LDAP_REQ_SEARCH );
00189 
00190               ctrl[c].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
00191               ctrl[c].ldctl_iscritical = 0;
00192 
00193               ps_ber = (BerElement *)&ps_berbuf;
00194               ber_init2( ps_ber, NULL, LBER_USE_DER );
00195 
00196               /* return size of 0 -- no estimate */
00197               ber_printf( ps_ber, "{iO}", 0, &cookie ); 
00198 
00199               if ( ber_flatten2( ps_ber, &ctrl[c].ldctl_value, 0 ) == -1 ) {
00200                      goto done;
00201               }
00202               
00203               ctrls[c] = &ctrl[c];
00204               c++;
00205        }
00206 
00207        /* terminate controls array */
00208        ctrls[c] = NULL;
00209        rs->sr_ctrls = ctrls;
00210        rs->sr_err = rc;
00211 
00212 respond:;
00213        send_ldap_result( op, rs );
00214        rs->sr_ctrls = NULL;
00215 
00216 done:;
00217        if ( ps_ber != NULL ) {
00218               (void) ber_free_buf( ps_ber );
00219        }
00220 
00221        if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
00222               slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
00223               slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
00224        }
00225 
00226        if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
00227               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
00228               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
00229        }
00230 
00231        return rs->sr_err;
00232 }
00233 
00234 /* add, delete, modify, modrdn, search */
00235 static int
00236 null_back_success( Operation *op, SlapReply *rs )
00237 {
00238        return null_back_respond( op, rs, LDAP_SUCCESS );
00239 }
00240 
00241 /* compare */
00242 static int
00243 null_back_false( Operation *op, SlapReply *rs )
00244 {
00245        return null_back_respond( op, rs, LDAP_COMPARE_FALSE );
00246 }
00247 
00248 
00249 /* for overlays */
00250 static int
00251 null_back_entry_get(
00252        Operation *op,
00253        struct berval *ndn,
00254        ObjectClass *oc,
00255        AttributeDescription *at,
00256        int rw,
00257        Entry **ent )
00258 {
00259        /* don't admit the object isn't there */
00260        return oc || at ? LDAP_NO_SUCH_ATTRIBUTE : LDAP_BUSY;
00261 }
00262 
00263 
00264 /* Slap tools */
00265 
00266 static int
00267 null_tool_entry_open( BackendDB *be, int mode )
00268 {
00269        return 0;
00270 }
00271 
00272 static int
00273 null_tool_entry_close( BackendDB *be )
00274 {
00275        assert( be != NULL );
00276        return 0;
00277 }
00278 
00279 static ID
00280 null_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
00281 {
00282        return NOID;
00283 }
00284 
00285 static ID
00286 null_tool_entry_next( BackendDB *be )
00287 {
00288        return NOID;
00289 }
00290 
00291 static Entry *
00292 null_tool_entry_get( BackendDB *be, ID id )
00293 {
00294        assert( slapMode & SLAP_TOOL_MODE );
00295        return NULL;
00296 }
00297 
00298 static ID
00299 null_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
00300 {
00301        assert( slapMode & SLAP_TOOL_MODE );
00302        assert( text != NULL );
00303        assert( text->bv_val != NULL );
00304        assert( text->bv_val[0] == '\0' ); /* overconservative? */
00305 
00306        e->e_id = ((struct null_info *) be->be_private)->ni_nextid++;
00307        return e->e_id;
00308 }
00309 
00310 
00311 /* Setup */
00312 
00313 static int
00314 null_cf_gen( ConfigArgs *c )
00315 {
00316        struct null_info *ni = (struct null_info *) c->be->be_private;
00317 
00318        if ( c->op == SLAP_CONFIG_EMIT ) {
00319               c->value_int = ni->ni_bind_allowed;
00320               return LDAP_SUCCESS;
00321        } else if ( c->op == LDAP_MOD_DELETE ) {
00322               ni->ni_bind_allowed = 0;
00323               return LDAP_SUCCESS;
00324        }
00325 
00326        ni->ni_bind_allowed = c->value_int;
00327        return LDAP_SUCCESS;
00328 }
00329 
00330 static int
00331 null_back_db_init( BackendDB *be, ConfigReply *cr )
00332 {
00333        struct null_info *ni = ch_calloc( 1, sizeof(struct null_info) );
00334        ni->ni_bind_allowed = 0;
00335        ni->ni_nextid = 1;
00336        be->be_private = ni;
00337        be->be_cf_ocs = be->bd_info->bi_cf_ocs;
00338        return 0;
00339 }
00340 
00341 static int
00342 null_back_db_destroy( Backend *be, ConfigReply *cr )
00343 {
00344        free( be->be_private );
00345        return 0;
00346 }
00347 
00348 
00349 int
00350 null_back_initialize( BackendInfo *bi )
00351 {
00352        static char *controls[] = {
00353               LDAP_CONTROL_ASSERT,
00354               LDAP_CONTROL_MANAGEDSAIT,
00355               LDAP_CONTROL_NOOP,
00356               LDAP_CONTROL_PAGEDRESULTS,
00357               LDAP_CONTROL_SUBENTRIES,
00358               LDAP_CONTROL_PRE_READ,
00359               LDAP_CONTROL_POST_READ,
00360               LDAP_CONTROL_X_PERMISSIVE_MODIFY,
00361               NULL
00362        };
00363 
00364        Debug( LDAP_DEBUG_TRACE,
00365               "null_back_initialize: initialize null backend\n", 0, 0, 0 );
00366 
00367        bi->bi_flags |=
00368               SLAP_BFLAG_INCREMENT |
00369               SLAP_BFLAG_SUBENTRIES |
00370               SLAP_BFLAG_ALIASES |
00371               SLAP_BFLAG_REFERRALS;
00372 
00373        bi->bi_controls = controls;
00374 
00375        bi->bi_open = 0;
00376        bi->bi_close = 0;
00377        bi->bi_config = 0;
00378        bi->bi_destroy = 0;
00379 
00380        bi->bi_db_init = null_back_db_init;
00381        bi->bi_db_config = config_generic_wrapper;
00382        bi->bi_db_open = 0;
00383        bi->bi_db_close = 0;
00384        bi->bi_db_destroy = null_back_db_destroy;
00385 
00386        bi->bi_op_bind = null_back_bind;
00387        bi->bi_op_unbind = 0;
00388        bi->bi_op_search = null_back_success;
00389        bi->bi_op_compare = null_back_false;
00390        bi->bi_op_modify = null_back_success;
00391        bi->bi_op_modrdn = null_back_success;
00392        bi->bi_op_add = null_back_success;
00393        bi->bi_op_delete = null_back_success;
00394        bi->bi_op_abandon = 0;
00395 
00396        bi->bi_extended = 0;
00397 
00398        bi->bi_chk_referrals = 0;
00399 
00400        bi->bi_connection_init = 0;
00401        bi->bi_connection_destroy = 0;
00402 
00403        bi->bi_entry_get_rw = null_back_entry_get;
00404 
00405        bi->bi_tool_entry_open = null_tool_entry_open;
00406        bi->bi_tool_entry_close = null_tool_entry_close;
00407        bi->bi_tool_entry_first = backend_tool_entry_first;
00408        bi->bi_tool_entry_first_x = null_tool_entry_first_x;
00409        bi->bi_tool_entry_next = null_tool_entry_next;
00410        bi->bi_tool_entry_get = null_tool_entry_get;
00411        bi->bi_tool_entry_put = null_tool_entry_put;
00412 
00413        bi->bi_cf_ocs = nullocs;
00414        return config_register_schema( nullcfg, nullocs );
00415 }
00416 
00417 #if SLAPD_NULL == SLAPD_MOD_DYNAMIC
00418 
00419 /* conditionally define the init_module() function */
00420 SLAP_BACKEND_INIT_MODULE( null )
00421 
00422 #endif /* SLAPD_NULL == SLAPD_MOD_DYNAMIC */