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