Home | History | Annotate | Line # | Download | only in denyop
denyop.c revision 1.1.1.4
      1  1.1.1.2  lukem /*	$NetBSD: denyop.c,v 1.1.1.4 2014/05/28 09:58:27 tron Exp $	*/
      2  1.1.1.2  lukem 
      3      1.1  lukem /* denyop.c - Denies operations */
      4  1.1.1.4   tron /* $OpenLDAP$ */
      5      1.1  lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6      1.1  lukem  *
      7  1.1.1.4   tron  * 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