]> git.sur5r.net Git - openldap/blob - libraries/librewrite/info.c
Use ldap_unbind_ext(3)
[openldap] / libraries / librewrite / info.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2000-2003 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 /* ACKNOWLEDGEMENT:
16  * This work was initially developed by Pierangelo Masarati for
17  * inclusion in OpenLDAP Software.
18  */
19
20 #include <portable.h>
21
22 #include "rewrite-int.h"
23
24 /*
25  * Global data
26  */
27
28 /*
29  * This becomes the running context for subsequent calls to
30  * rewrite_parse; it can be altered only by a 
31  * rewriteContext config line or by a change in info.
32  */
33 struct rewrite_context *rewrite_int_curr_context = NULL;
34
35 /*
36  * Inits the info
37  */
38 struct rewrite_info *
39 rewrite_info_init(
40                 int mode
41 )
42 {
43         struct rewrite_info *info;
44         struct rewrite_context *context;
45
46         switch ( mode ) {
47         case REWRITE_MODE_ERR:
48         case REWRITE_MODE_OK:
49         case REWRITE_MODE_COPY_INPUT:
50         case REWRITE_MODE_USE_DEFAULT:
51                 break;
52         default:
53                 mode = REWRITE_MODE_USE_DEFAULT;
54                 break;
55                 /* return NULL */
56         }
57
58         /*
59          * Resets the running context for parsing ...
60          */
61         rewrite_int_curr_context = NULL;
62
63         info = calloc( sizeof( struct rewrite_info ), 1 );
64         if ( info == NULL ) {
65                 return NULL;
66         }
67
68         info->li_state = REWRITE_DEFAULT;
69         info->li_max_passes = REWRITE_MAX_PASSES;
70         info->li_rewrite_mode = mode;
71
72         /*
73          * Add the default (empty) rule
74          */
75         context = rewrite_context_create( info, REWRITE_DEFAULT_CONTEXT );
76         if ( context == NULL ) {
77                 free( info );
78                 return NULL;
79         }
80
81 #ifdef USE_REWRITE_LDAP_PVT_THREADS
82         if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
83                 free( info );
84                 return NULL;
85         }
86         if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
87                 free( info );
88                 return NULL;
89         }
90 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
91         
92         return info;
93 }
94
95 /*
96  * Cleans up the info structure
97  */
98 int
99 rewrite_info_delete(
100                 struct rewrite_info **pinfo
101 )
102 {
103         struct rewrite_info     *info;
104
105         assert( pinfo != NULL );
106         assert( *pinfo != NULL );
107
108         info = *pinfo;
109         
110         if ( info->li_context ) {
111                 avl_free( info->li_context, rewrite_context_free );
112         }
113         info->li_context = NULL;
114
115         if ( info->li_maps ) {
116                 avl_free( info->li_maps, rewrite_builtin_map_free );
117         }
118         info->li_context = NULL;
119
120         rewrite_session_destroy( info );
121
122 #ifdef USE_REWRITE_LDAP_PVT_THREADS
123         ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
124 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
125
126         rewrite_param_destroy( info );
127         
128 #ifdef USE_REWRITE_LDAP_PVT_THREADS
129         ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
130 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
131
132         free( info );
133         *pinfo = NULL;
134
135         return REWRITE_SUCCESS;
136 }
137
138 /*
139  * Rewrites a string according to context.
140  * If the engine is off, OK is returned, but the return string will be NULL.
141  * In case of 'unwilling to perform', UNWILLING is returned, and the
142  * return string will also be null. The same in case of error.
143  * Otherwise, OK is returned, and result will hold a newly allocated string
144  * with the rewriting.
145  * 
146  * What to do in case of non-existing rewrite context is still an issue.
147  * Four possibilities:
148  *      - error, 
149  *      - ok with NULL result, 
150  *      - ok with copy of string as result,
151  *      - use the default rewrite context.
152  */
153 int
154 rewrite(
155                 struct rewrite_info *info,
156                 const char *rewriteContext,
157                 const char *string,
158                 char **result
159 )
160 {
161         return rewrite_session( info, rewriteContext, 
162                         string, NULL, result );
163 }
164
165 int
166 rewrite_session(
167                 struct rewrite_info *info,
168                 const char *rewriteContext,
169                 const char *string,
170                 const void *cookie,
171                 char **result
172 )
173 {
174         struct rewrite_context *context;
175         struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
176         int rc;
177         
178         assert( info != NULL );
179         assert( rewriteContext != NULL );
180         assert( string != NULL );
181         assert( result != NULL );
182
183         /*
184          * cookie can be null; means: don't care about session stuff
185          */
186
187         *result = NULL;
188         op.lo_cookie = cookie;
189         
190         /*
191          * Engine not on means no failure, but explicit no rewriting
192          */
193         if ( info->li_state != REWRITE_ON ) {
194                 rc = REWRITE_REGEXEC_OK;
195                 goto rc_return;
196         }
197         
198         /*
199          * Undefined context means no rewriting also
200          * (conservative, are we sure it's what we want?)
201          */
202         context = rewrite_context_find( info, rewriteContext );
203         if ( context == NULL ) {
204                 switch ( info->li_rewrite_mode ) {
205                 case REWRITE_MODE_ERR:
206                         rc = REWRITE_REGEXEC_ERR;
207                         goto rc_return;
208                         
209                 case REWRITE_MODE_OK:
210                         rc = REWRITE_REGEXEC_OK;
211                         goto rc_return;
212
213                 case REWRITE_MODE_COPY_INPUT:
214                         *result = strdup( string );
215                         rc = REWRITE_REGEXEC_OK;
216                         goto rc_return;
217
218                 case REWRITE_MODE_USE_DEFAULT:
219                         context = rewrite_context_find( info,
220                                         REWRITE_DEFAULT_CONTEXT );
221                         break;
222                 }
223         }
224
225 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
226         op.lo_string = strdup( string );
227         if ( op.lo_string == NULL ) {
228                 rc = REWRITE_REGEXEC_ERR;
229                 goto rc_return;
230         }
231 #endif
232         
233         /*
234          * Applies rewrite context
235          */
236         rc = rewrite_context_apply( info, &op, context, string, result );
237         assert( op.lo_depth == 0 );
238
239 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */        
240         free( op.lo_string );
241 #endif
242         
243         switch ( rc ) {
244         /*
245          * Success
246          */
247         case REWRITE_REGEXEC_OK:
248         case REWRITE_REGEXEC_STOP:
249                 /*
250                  * If rewrite succeeded return OK regardless of how
251                  * the successful rewriting was obtained!
252                  */
253                 rc = REWRITE_REGEXEC_OK;
254                 break;
255                 
256         
257         /*
258          * Internal or forced error, return = NULL; rc already OK.
259          */
260         case REWRITE_REGEXEC_UNWILLING:
261         case REWRITE_REGEXEC_ERR:
262         default:
263                 if ( *result != NULL ) {
264                         free( *result );
265                         *result = NULL;
266                 }
267         }
268
269 rc_return:;
270         if ( op.lo_vars ) {
271                 rewrite_var_delete( op.lo_vars );
272         }
273         
274         return rc;
275 }
276