Back to index

openldap  2.4.31
denyop.c
Go to the documentation of this file.
00001 /* denyop.c - Denies operations */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2004-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 initially developed by Pierangelo Masarati for inclusion in
00018  * OpenLDAP Software.
00019  */
00020 
00021 #include "portable.h"
00022 
00023 #ifdef SLAPD_OVER_DENYOP
00024 
00025 #include <stdio.h>
00026 
00027 #include <ac/string.h>
00028 #include <ac/socket.h>
00029 
00030 #include "slap.h"
00031 
00032 /* This overlay provides a quick'n'easy way to deny selected operations
00033  * for a database whose backend implements the operations.  It is intended
00034  * to be less expensive than ACLs because its evaluation occurs before
00035  * any backend specific operation is actually even initiated.
00036  */
00037 
00038 enum {
00039        denyop_add = 0,
00040        denyop_bind,
00041        denyop_compare,
00042        denyop_delete,
00043        denyop_extended,
00044        denyop_modify,
00045        denyop_modrdn,
00046        denyop_search,
00047        denyop_unbind
00048 } denyop_e;
00049 
00050 typedef struct denyop_info {
00051        int do_op[denyop_unbind + 1];
00052 } denyop_info;
00053 
00054 static int
00055 denyop_func( Operation *op, SlapReply *rs )
00056 {
00057        slap_overinst        *on = (slap_overinst *) op->o_bd->bd_info;
00058        denyop_info          *oi = (denyop_info *)on->on_bi.bi_private;
00059        int                  deny = 0;
00060 
00061        switch( op->o_tag ) {
00062        case LDAP_REQ_BIND:
00063               deny = oi->do_op[denyop_bind];
00064               break;
00065 
00066        case LDAP_REQ_ADD:
00067               deny = oi->do_op[denyop_add];
00068               break;
00069 
00070        case LDAP_REQ_DELETE:
00071               deny = oi->do_op[denyop_delete];
00072               break;
00073 
00074        case LDAP_REQ_MODRDN:
00075               deny = oi->do_op[denyop_modrdn];
00076               break;
00077 
00078        case LDAP_REQ_MODIFY:
00079               deny = oi->do_op[denyop_modify];
00080               break;
00081 
00082        case LDAP_REQ_COMPARE:
00083               deny = oi->do_op[denyop_compare];
00084               break;
00085 
00086        case LDAP_REQ_SEARCH:
00087               deny = oi->do_op[denyop_search];
00088               break;
00089 
00090        case LDAP_REQ_EXTENDED:
00091               deny = oi->do_op[denyop_extended];
00092               break;
00093 
00094        case LDAP_REQ_UNBIND:
00095               deny = oi->do_op[denyop_unbind];
00096               break;
00097        }
00098 
00099        if ( !deny ) {
00100               return SLAP_CB_CONTINUE;
00101        }
00102 
00103        op->o_bd->bd_info = (BackendInfo *)on->on_info;
00104        send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
00105                      "operation not allowed within namingContext" );
00106 
00107        return 0;
00108 }
00109 
00110 static int
00111 denyop_over_init(
00112        BackendDB *be
00113 )
00114 {
00115        slap_overinst        *on = (slap_overinst *) be->bd_info;
00116        denyop_info          *oi;
00117 
00118        oi = (denyop_info *)ch_malloc(sizeof(denyop_info));
00119        memset(oi, 0, sizeof(denyop_info));
00120        on->on_bi.bi_private = oi;
00121 
00122        return 0;
00123 }
00124 
00125 static int
00126 denyop_config(
00127     BackendDB *be,
00128     const char       *fname,
00129     int              lineno,
00130     int              argc,
00131     char      **argv
00132 )
00133 {
00134        slap_overinst        *on = (slap_overinst *) be->bd_info;
00135        denyop_info          *oi = (denyop_info *)on->on_bi.bi_private;
00136 
00137        if ( strcasecmp( argv[0], "denyop" ) == 0 ) {
00138               char *op;
00139 
00140               if ( argc != 2 ) {
00141                      Debug( LDAP_DEBUG_ANY, "%s: line %d: "
00142                             "operation list missing in "
00143                             "\"denyop <op-list>\" line.\n",
00144                             fname, lineno, 0 );
00145                      return( 1 );
00146               }
00147 
00148               /* The on->on_bi.bi_private pointer can be used for
00149                * anything this instance of the overlay needs.
00150                */
00151 
00152               op = argv[1];
00153               do {
00154                      char   *next = strchr( op, ',' );
00155 
00156                      if ( next ) {
00157                             next[0] = '\0';
00158                             next++;
00159                      }
00160 
00161                      if ( strcmp( op, "add" ) == 0 ) {
00162                             oi->do_op[denyop_add] = 1;
00163 
00164                      } else if ( strcmp( op, "bind" ) == 0 ) {
00165                             oi->do_op[denyop_bind] = 1;
00166 
00167                      } else if ( strcmp( op, "compare" ) == 0 ) {
00168                             oi->do_op[denyop_compare] = 1;
00169 
00170                      } else if ( strcmp( op, "delete" ) == 0 ) {
00171                             oi->do_op[denyop_delete] = 1;
00172 
00173                      } else if ( strcmp( op, "extended" ) == 0 ) {
00174                             oi->do_op[denyop_extended] = 1;
00175 
00176                      } else if ( strcmp( op, "modify" ) == 0 ) {
00177                             oi->do_op[denyop_modify] = 1;
00178 
00179                      } else if ( strcmp( op, "modrdn" ) == 0 ) {
00180                             oi->do_op[denyop_modrdn] = 1;
00181 
00182                      } else if ( strcmp( op, "search" ) == 0 ) {
00183                             oi->do_op[denyop_search] = 1;
00184 
00185                      } else if ( strcmp( op, "unbind" ) == 0 ) {
00186                             oi->do_op[denyop_unbind] = 1;
00187 
00188                      } else {
00189                             Debug( LDAP_DEBUG_ANY, "%s: line %d: "
00190                                    "unknown operation \"%s\" at "
00191                                    "\"denyop <op-list>\" line.\n",
00192                                    fname, lineno, op );
00193                             return( 1 );
00194                      }
00195 
00196                      op = next;
00197               } while ( op );
00198 
00199        } else {
00200               return SLAP_CONF_UNKNOWN;
00201        }
00202        return 0;
00203 }
00204 
00205 static int
00206 denyop_destroy(
00207        BackendDB *be
00208 )
00209 {
00210        slap_overinst *on = (slap_overinst *) be->bd_info;
00211        denyop_info   *oi = (denyop_info *)on->on_bi.bi_private;
00212 
00213        if ( oi ) {
00214               ch_free( oi );
00215        }
00216 
00217        return 0;
00218 }
00219 
00220 /* This overlay is set up for dynamic loading via moduleload. For static
00221  * configuration, you'll need to arrange for the slap_overinst to be
00222  * initialized and registered by some other function inside slapd.
00223  */
00224 
00225 static slap_overinst denyop;
00226 
00227 int
00228 denyop_initialize( void )
00229 {
00230        memset( &denyop, 0, sizeof( slap_overinst ) );
00231        denyop.on_bi.bi_type = "denyop";
00232        denyop.on_bi.bi_db_init = denyop_over_init;
00233        denyop.on_bi.bi_db_config = denyop_config;
00234        denyop.on_bi.bi_db_destroy = denyop_destroy;
00235 
00236        denyop.on_bi.bi_op_bind = denyop_func;
00237        denyop.on_bi.bi_op_search = denyop_func;
00238        denyop.on_bi.bi_op_compare = denyop_func;
00239        denyop.on_bi.bi_op_modify = denyop_func;
00240        denyop.on_bi.bi_op_modrdn = denyop_func;
00241        denyop.on_bi.bi_op_add = denyop_func;
00242        denyop.on_bi.bi_op_delete = denyop_func;
00243        denyop.on_bi.bi_extended = denyop_func;
00244        denyop.on_bi.bi_op_unbind = denyop_func;
00245 
00246        denyop.on_response = NULL /* denyop_response */ ;
00247 
00248        return overlay_register( &denyop );
00249 }
00250 
00251 #if SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC
00252 int
00253 init_module( int argc, char *argv[] )
00254 {
00255        return denyop_initialize();
00256 }
00257 #endif /* SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC */
00258 
00259 #endif /* defined(SLAPD_OVER_DENYOP) */