Home | History | Annotate | Line # | Download | only in denyop
denyop.c revision 1.1.1.3.24.1
      1  1.1.1.3.24.1    tls /*	$NetBSD: denyop.c,v 1.1.1.3.24.1 2014/08/10 07:09:43 tls Exp $	*/
      2       1.1.1.2  lukem 
      3           1.1  lukem /* denyop.c - Denies operations */
      4  1.1.1.3.24.1    tls /* $OpenLDAP$ */
      5           1.1  lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6           1.1  lukem  *
      7  1.1.1.3.24.1    tls  * Copyright 2004-2014 The OpenLDAP Foundation.
      8           1.1  lukem  * All rights reserved.
      9           1.1  lukem  *
     10           1.1  lukem  * Redistribution and use in source and binary forms, with or without
     11           1.1  lukem  * modification, are permitted only as authorized by the OpenLDAP
     12           1.1  lukem  * Public License.
     13           1.1  lukem  *
     14           1.1  lukem  * A copy of this license is available in the file LICENSE in the
     15           1.1  lukem  * top-level directory of the distribution or, alternatively, at
     16           1.1  lukem  * <http://www.OpenLDAP.org/license.html>.
     17           1.1  lukem  */
     18           1.1  lukem /* ACKNOWLEDGEMENTS:
     19           1.1  lukem  * This work was initially developed by Pierangelo Masarati for inclusion in
     20           1.1  lukem  * OpenLDAP Software.
     21           1.1  lukem  */
     22           1.1  lukem 
     23           1.1  lukem #include "portable.h"
     24           1.1  lukem 
     25           1.1  lukem #ifdef SLAPD_OVER_DENYOP
     26           1.1  lukem 
     27           1.1  lukem #include <stdio.h>
     28           1.1  lukem 
     29           1.1  lukem #include <ac/string.h>
     30           1.1  lukem #include <ac/socket.h>
     31           1.1  lukem 
     32           1.1  lukem #include "slap.h"
     33           1.1  lukem 
     34           1.1  lukem /* This overlay provides a quick'n'easy way to deny selected operations
     35           1.1  lukem  * for a database whose backend implements the operations.  It is intended
     36           1.1  lukem  * to be less expensive than ACLs because its evaluation occurs before
     37           1.1  lukem  * any backend specific operation is actually even initiated.
     38           1.1  lukem  */
     39           1.1  lukem 
     40           1.1  lukem enum {
     41           1.1  lukem 	denyop_add = 0,
     42           1.1  lukem 	denyop_bind,
     43           1.1  lukem 	denyop_compare,
     44           1.1  lukem 	denyop_delete,
     45           1.1  lukem 	denyop_extended,
     46           1.1  lukem 	denyop_modify,
     47           1.1  lukem 	denyop_modrdn,
     48           1.1  lukem 	denyop_search,
     49           1.1  lukem 	denyop_unbind
     50           1.1  lukem } denyop_e;
     51           1.1  lukem 
     52           1.1  lukem typedef struct denyop_info {
     53           1.1  lukem 	int do_op[denyop_unbind + 1];
     54           1.1  lukem } denyop_info;
     55           1.1  lukem 
     56           1.1  lukem static int
     57           1.1  lukem denyop_func( Operation *op, SlapReply *rs )
     58           1.1  lukem {
     59           1.1  lukem 	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;
     60           1.1  lukem 	denyop_info		*oi = (denyop_info *)on->on_bi.bi_private;
     61           1.1  lukem 	int			deny = 0;
     62           1.1  lukem 
     63           1.1  lukem 	switch( op->o_tag ) {
     64           1.1  lukem 	case LDAP_REQ_BIND:
     65           1.1  lukem 		deny = oi->do_op[denyop_bind];
     66           1.1  lukem 		break;
     67           1.1  lukem 
     68           1.1  lukem 	case LDAP_REQ_ADD:
     69           1.1  lukem 		deny = oi->do_op[denyop_add];
     70           1.1  lukem 		break;
     71           1.1  lukem 
     72           1.1  lukem 	case LDAP_REQ_DELETE:
     73           1.1  lukem 		deny = oi->do_op[denyop_delete];
     74           1.1  lukem 		break;
     75           1.1  lukem 
     76           1.1  lukem 	case LDAP_REQ_MODRDN:
     77           1.1  lukem 		deny = oi->do_op[denyop_modrdn];
     78           1.1  lukem 		break;
     79           1.1  lukem 
     80           1.1  lukem 	case LDAP_REQ_MODIFY:
     81           1.1  lukem 		deny = oi->do_op[denyop_modify];
     82           1.1  lukem 		break;
     83           1.1  lukem 
     84           1.1  lukem 	case LDAP_REQ_COMPARE:
     85           1.1  lukem 		deny = oi->do_op[denyop_compare];
     86           1.1  lukem 		break;
     87           1.1  lukem 
     88           1.1  lukem 	case LDAP_REQ_SEARCH:
     89           1.1  lukem 		deny = oi->do_op[denyop_search];
     90           1.1  lukem 		break;
     91           1.1  lukem 
     92           1.1  lukem 	case LDAP_REQ_EXTENDED:
     93           1.1  lukem 		deny = oi->do_op[denyop_extended];
     94           1.1  lukem 		break;
     95           1.1  lukem 
     96           1.1  lukem 	case LDAP_REQ_UNBIND:
     97           1.1  lukem 		deny = oi->do_op[denyop_unbind];
     98           1.1  lukem 		break;
     99           1.1  lukem 	}
    100           1.1  lukem 
    101           1.1  lukem 	if ( !deny ) {
    102           1.1  lukem 		return SLAP_CB_CONTINUE;
    103           1.1  lukem 	}
    104           1.1  lukem 
    105           1.1  lukem 	op->o_bd->bd_info = (BackendInfo *)on->on_info;
    106           1.1  lukem 	send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
    107           1.1  lukem 			"operation not allowed within namingContext" );
    108           1.1  lukem 
    109           1.1  lukem 	return 0;
    110           1.1  lukem }
    111           1.1  lukem 
    112           1.1  lukem static int
    113           1.1  lukem denyop_over_init(
    114           1.1  lukem 	BackendDB *be
    115           1.1  lukem )
    116           1.1  lukem {
    117           1.1  lukem 	slap_overinst		*on = (slap_overinst *) be->bd_info;
    118           1.1  lukem 	denyop_info		*oi;
    119           1.1  lukem 
    120           1.1  lukem 	oi = (denyop_info *)ch_malloc(sizeof(denyop_info));
    121           1.1  lukem 	memset(oi, 0, sizeof(denyop_info));
    122           1.1  lukem 	on->on_bi.bi_private = oi;
    123           1.1  lukem 
    124           1.1  lukem 	return 0;
    125           1.1  lukem }
    126           1.1  lukem 
    127           1.1  lukem static int
    128           1.1  lukem denyop_config(
    129           1.1  lukem     BackendDB	*be,
    130           1.1  lukem     const char	*fname,
    131           1.1  lukem     int		lineno,
    132           1.1  lukem     int		argc,
    133           1.1  lukem     char	**argv
    134           1.1  lukem )
    135           1.1  lukem {
    136           1.1  lukem 	slap_overinst		*on = (slap_overinst *) be->bd_info;
    137           1.1  lukem 	denyop_info		*oi = (denyop_info *)on->on_bi.bi_private;
    138           1.1  lukem 
    139           1.1  lukem 	if ( strcasecmp( argv[0], "denyop" ) == 0 ) {
    140           1.1  lukem 		char *op;
    141           1.1  lukem 
    142           1.1  lukem 		if ( argc != 2 ) {
    143           1.1  lukem 			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
    144           1.1  lukem 				"operation list missing in "
    145           1.1  lukem 				"\"denyop <op-list>\" line.\n",
    146           1.1  lukem 				fname, lineno, 0 );
    147           1.1  lukem 			return( 1 );
    148           1.1  lukem 		}
    149           1.1  lukem 
    150           1.1  lukem 		/* The on->on_bi.bi_private pointer can be used for
    151           1.1  lukem 		 * anything this instance of the overlay needs.
    152           1.1  lukem 		 */
    153           1.1  lukem 
    154           1.1  lukem 		op = argv[1];
    155           1.1  lukem 		do {
    156           1.1  lukem 			char	*next = strchr( op, ',' );
    157           1.1  lukem 
    158           1.1  lukem 			if ( next ) {
    159           1.1  lukem 				next[0] = '\0';
    160           1.1  lukem 				next++;
    161           1.1  lukem 			}
    162           1.1  lukem 
    163           1.1  lukem 			if ( strcmp( op, "add" ) == 0 ) {
    164           1.1  lukem 				oi->do_op[denyop_add] = 1;
    165           1.1  lukem 
    166           1.1  lukem 			} else if ( strcmp( op, "bind" ) == 0 ) {
    167           1.1  lukem 				oi->do_op[denyop_bind] = 1;
    168           1.1  lukem 
    169           1.1  lukem 			} else if ( strcmp( op, "compare" ) == 0 ) {
    170           1.1  lukem 				oi->do_op[denyop_compare] = 1;
    171           1.1  lukem 
    172           1.1  lukem 			} else if ( strcmp( op, "delete" ) == 0 ) {
    173           1.1  lukem 				oi->do_op[denyop_delete] = 1;
    174           1.1  lukem 
    175           1.1  lukem 			} else if ( strcmp( op, "extended" ) == 0 ) {
    176           1.1  lukem 				oi->do_op[denyop_extended] = 1;
    177           1.1  lukem 
    178           1.1  lukem 			} else if ( strcmp( op, "modify" ) == 0 ) {
    179           1.1  lukem 				oi->do_op[denyop_modify] = 1;
    180           1.1  lukem 
    181           1.1  lukem 			} else if ( strcmp( op, "modrdn" ) == 0 ) {
    182           1.1  lukem 				oi->do_op[denyop_modrdn] = 1;
    183           1.1  lukem 
    184           1.1  lukem 			} else if ( strcmp( op, "search" ) == 0 ) {
    185           1.1  lukem 				oi->do_op[denyop_search] = 1;
    186           1.1  lukem 
    187           1.1  lukem 			} else if ( strcmp( op, "unbind" ) == 0 ) {
    188           1.1  lukem 				oi->do_op[denyop_unbind] = 1;
    189           1.1  lukem 
    190           1.1  lukem 			} else {
    191           1.1  lukem 				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
    192           1.1  lukem 					"unknown operation \"%s\" at "
    193           1.1  lukem 					"\"denyop <op-list>\" line.\n",
    194           1.1  lukem 					fname, lineno, op );
    195           1.1  lukem 				return( 1 );
    196           1.1  lukem 			}
    197           1.1  lukem 
    198           1.1  lukem 			op = next;
    199           1.1  lukem 		} while ( op );
    200           1.1  lukem 
    201           1.1  lukem 	} else {
    202           1.1  lukem 		return SLAP_CONF_UNKNOWN;
    203           1.1  lukem 	}
    204           1.1  lukem 	return 0;
    205           1.1  lukem }
    206           1.1  lukem 
    207           1.1  lukem static int
    208           1.1  lukem denyop_destroy(
    209           1.1  lukem 	BackendDB *be
    210           1.1  lukem )
    211           1.1  lukem {
    212           1.1  lukem 	slap_overinst	*on = (slap_overinst *) be->bd_info;
    213           1.1  lukem 	denyop_info	*oi = (denyop_info *)on->on_bi.bi_private;
    214           1.1  lukem 
    215           1.1  lukem 	if ( oi ) {
    216           1.1  lukem 		ch_free( oi );
    217           1.1  lukem 	}
    218           1.1  lukem 
    219           1.1  lukem 	return 0;
    220           1.1  lukem }
    221           1.1  lukem 
    222           1.1  lukem /* This overlay is set up for dynamic loading via moduleload. For static
    223           1.1  lukem  * configuration, you'll need to arrange for the slap_overinst to be
    224           1.1  lukem  * initialized and registered by some other function inside slapd.
    225           1.1  lukem  */
    226           1.1  lukem 
    227           1.1  lukem static slap_overinst denyop;
    228           1.1  lukem 
    229           1.1  lukem int
    230           1.1  lukem denyop_initialize( void )
    231           1.1  lukem {
    232           1.1  lukem 	memset( &denyop, 0, sizeof( slap_overinst ) );
    233           1.1  lukem 	denyop.on_bi.bi_type = "denyop";
    234           1.1  lukem 	denyop.on_bi.bi_db_init = denyop_over_init;
    235           1.1  lukem 	denyop.on_bi.bi_db_config = denyop_config;
    236           1.1  lukem 	denyop.on_bi.bi_db_destroy = denyop_destroy;
    237           1.1  lukem 
    238           1.1  lukem 	denyop.on_bi.bi_op_bind = denyop_func;
    239           1.1  lukem 	denyop.on_bi.bi_op_search = denyop_func;
    240           1.1  lukem 	denyop.on_bi.bi_op_compare = denyop_func;
    241           1.1  lukem 	denyop.on_bi.bi_op_modify = denyop_func;
    242           1.1  lukem 	denyop.on_bi.bi_op_modrdn = denyop_func;
    243           1.1  lukem 	denyop.on_bi.bi_op_add = denyop_func;
    244           1.1  lukem 	denyop.on_bi.bi_op_delete = denyop_func;
    245           1.1  lukem 	denyop.on_bi.bi_extended = denyop_func;
    246           1.1  lukem 	denyop.on_bi.bi_op_unbind = denyop_func;
    247           1.1  lukem 
    248           1.1  lukem 	denyop.on_response = NULL /* denyop_response */ ;
    249           1.1  lukem 
    250           1.1  lukem 	return overlay_register( &denyop );
    251           1.1  lukem }
    252           1.1  lukem 
    253           1.1  lukem #if SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC
    254           1.1  lukem int
    255           1.1  lukem init_module( int argc, char *argv[] )
    256           1.1  lukem {
    257           1.1  lukem 	return denyop_initialize();
    258           1.1  lukem }
    259           1.1  lukem #endif /* SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC */
    260           1.1  lukem 
    261           1.1  lukem #endif /* defined(SLAPD_OVER_DENYOP) */
    262