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