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