From 28285002a16279c0bfdbbecd114e026cdf1bd899 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 9 Mar 2004 10:23:19 +0000 Subject: [PATCH] deny an operation --- servers/slapd/overlays/Makefile.in | 7 +- servers/slapd/overlays/denyop.c | 254 +++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 2 deletions(-) create mode 100644 servers/slapd/overlays/denyop.c diff --git a/servers/slapd/overlays/Makefile.in b/servers/slapd/overlays/Makefile.in index 00776ebaa7..66c52390b6 100644 --- a/servers/slapd/overlays/Makefile.in +++ b/servers/slapd/overlays/Makefile.in @@ -14,9 +14,9 @@ ## . SRCS = overlays.c dyngroup.c pcache.c \ - rwm.c rwmconf.c rwmdn.c rwmmap.c + rwm.c rwmconf.c rwmdn.c rwmmap.c denyop.c OBJS = overlays.lo dyngroup.lo pcache.lo \ - rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo + rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo denyop.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries @@ -42,6 +42,9 @@ pcache.la : pcache.lo $(@PLAT@_LINK_LIBS) rwm.la : rwm.lo $(@PLAT@_LINK_LIBS) $(LTLINK_MOD) -module -o $@ rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo version.lo $(LINK_LIBS) +denyop.la : denyop.lo $(@PLAT@_LINK_LIBS) + $(LTLINK_MOD) -module -o $@ denyop.lo version.lo $(LINK_LIBS) + install-local: $(PROGRAMS) @if test -n "$?" ; then \ $(MKDIR) $(DESTDIR)$(moduledir); \ diff --git a/servers/slapd/overlays/denyop.c b/servers/slapd/overlays/denyop.c new file mode 100644 index 0000000000..4c45af2239 --- /dev/null +++ b/servers/slapd/overlays/denyop.c @@ -0,0 +1,254 @@ +/* denyop.c - Denies operations */ +/* This work is part of OpenLDAP Software . + * + * Copyright 2004 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Pierangelo Masarati for inclusion in + * OpenLDAP Software. + */ + +#include "portable.h" + +#ifdef SLAPD_OVER_DENYOP + +#include + +#include +#include + +#include "slap.h" + +/* This overlay provides a quick'n'easy way to deny selected operations + * for a database whose backend implements the operations. It is intended + * to be less expensive than ACLs because its evaluation occurs before + * any backend specific operation is actually even initiated. + */ + +enum { + denyop_add = 0, + denyop_bind, + denyop_compare, + denyop_delete, + denyop_extended, + denyop_modify, + denyop_modrdn, + denyop_search, + denyop_unbind +} denyop_e; + +typedef struct denyop_info { + int do_op[denyop_unbind + 1]; +} denyop_info; + +static int +denyop_func( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + denyop_info *oi = (denyop_info *)on->on_bi.bi_private; + int deny = 0; + + switch( op->o_tag ) { + case LDAP_REQ_BIND: + deny = oi->do_op[denyop_bind]; + break; + + case LDAP_REQ_ADD: + deny = oi->do_op[denyop_add]; + break; + + case LDAP_REQ_DELETE: + deny = oi->do_op[denyop_delete]; + break; + + case LDAP_REQ_MODRDN: + deny = oi->do_op[denyop_modrdn]; + break; + + case LDAP_REQ_MODIFY: + deny = oi->do_op[denyop_modify]; + break; + + case LDAP_REQ_COMPARE: + deny = oi->do_op[denyop_compare]; + break; + + case LDAP_REQ_SEARCH: + deny = oi->do_op[denyop_search]; + break; + + case LDAP_REQ_EXTENDED: + deny = oi->do_op[denyop_extended]; + break; + + case LDAP_REQ_UNBIND: + deny = oi->do_op[denyop_unbind]; + break; + } + + if ( !deny ) { + return SLAP_CB_CONTINUE; + } + + op->o_bd->bd_info = (BackendInfo *)on->on_info; + send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, + "operation not allowed within namingContext" ); + + return 0; +} + +static int +denyop_over_init( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + denyop_info *oi; + + oi = (denyop_info *)ch_malloc(sizeof(denyop_info)); + memset(oi, 0, sizeof(denyop_info)); + on->on_bi.bi_private = oi; + + return 0; +} + +static int +denyop_config( + BackendDB *be, + const char *fname, + int lineno, + int argc, + char **argv +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + denyop_info *oi = (denyop_info *)on->on_bi.bi_private; + + if ( strcasecmp( argv[0], "denyop" ) == 0 ) { + char *op; + + if ( argc != 2 ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "operation list missing in " + "\"denyop \" line.\n", + fname, lineno, 0 ); + return( 1 ); + } + + /* The on->on_bi.bi_private pointer can be used for + * anything this instance of the overlay needs. + */ + + op = argv[1]; + do { + char *next = strchr( op, ',' ); + + if ( next ) { + next[0] = '\0'; + next++; + } + + if ( strcmp( op, "add" ) == 0 ) { + oi->do_op[denyop_add] = 1; + + } else if ( strcmp( op, "bind" ) == 0 ) { + oi->do_op[denyop_bind] = 1; + + } else if ( strcmp( op, "compare" ) == 0 ) { + oi->do_op[denyop_compare] = 1; + + } else if ( strcmp( op, "delete" ) == 0 ) { + oi->do_op[denyop_delete] = 1; + + } else if ( strcmp( op, "extended" ) == 0 ) { + oi->do_op[denyop_extended] = 1; + + } else if ( strcmp( op, "modify" ) == 0 ) { + oi->do_op[denyop_modify] = 1; + + } else if ( strcmp( op, "modrdn" ) == 0 ) { + oi->do_op[denyop_modrdn] = 1; + + } else if ( strcmp( op, "search" ) == 0 ) { + oi->do_op[denyop_search] = 1; + + } else if ( strcmp( op, "unbind" ) == 0 ) { + oi->do_op[denyop_unbind] = 1; + + } else { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "unknown operation \"%s\" " + "\"denyop \" line.\n", + op, fname, lineno ); + return( 1 ); + } + + op = next; + } while ( op ); + + } else { + return SLAP_CONF_UNKNOWN; + } + return 0; +} + +static int +denyop_destroy( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + denyop_info *oi = (denyop_info *)on->on_bi.bi_private; + + if ( oi ) { + ch_free( oi ); + } + + return 0; +} + +/* This overlay is set up for dynamic loading via moduleload. For static + * configuration, you'll need to arrange for the slap_overinst to be + * initialized and registered by some other function inside slapd. + */ + +static slap_overinst denyop; + +int denyop_init() { + memset( &denyop, 0, sizeof( slap_overinst ) ); + denyop.on_bi.bi_type = "denyop"; + denyop.on_bi.bi_db_init = denyop_over_init; + denyop.on_bi.bi_db_config = denyop_config; + denyop.on_bi.bi_db_destroy = denyop_destroy; + + denyop.on_bi.bi_op_bind = denyop_func; + denyop.on_bi.bi_op_search = denyop_func; + denyop.on_bi.bi_op_compare = denyop_func; + denyop.on_bi.bi_op_modify = denyop_func; + denyop.on_bi.bi_op_modrdn = denyop_func; + denyop.on_bi.bi_op_add = denyop_func; + denyop.on_bi.bi_op_delete = denyop_func; + denyop.on_bi.bi_extended = denyop_func; + denyop.on_bi.bi_op_unbind = denyop_func; + + denyop.on_response = NULL /* denyop_response */ ; + + return overlay_register( &denyop ); +} + +#if SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC +int init_module(int argc, char *argv[]) { + return denyop_init(); +} +#endif + +#endif /* defined(SLAPD_OVER_DENYOP) */ -- 2.39.5