denyop.c revision 1.1.1.4 1 /* $NetBSD: denyop.c,v 1.1.1.4 2014/05/28 09:58:27 tron Exp $ */
2
3 /* denyop.c - Denies operations */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2004-2014 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