session.c revision 1.1 1 1.1 lukem /* $OpenLDAP: pkg/ldap/libraries/librewrite/session.c,v 1.19.2.3 2008/02/11 23:26:42 kurt Exp $ */
2 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 1.1 lukem *
4 1.1 lukem * Copyright 2000-2008 The OpenLDAP Foundation.
5 1.1 lukem * All rights reserved.
6 1.1 lukem *
7 1.1 lukem * Redistribution and use in source and binary forms, with or without
8 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
9 1.1 lukem * Public License.
10 1.1 lukem *
11 1.1 lukem * A copy of this license is available in the file LICENSE in the
12 1.1 lukem * top-level directory of the distribution or, alternatively, at
13 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
14 1.1 lukem */
15 1.1 lukem /* ACKNOWLEDGEMENT:
16 1.1 lukem * This work was initially developed by Pierangelo Masarati for
17 1.1 lukem * inclusion in OpenLDAP Software.
18 1.1 lukem */
19 1.1 lukem
20 1.1 lukem #include <portable.h>
21 1.1 lukem
22 1.1 lukem #include "rewrite-int.h"
23 1.1 lukem
24 1.1 lukem /*
25 1.1 lukem * Compares two cookies
26 1.1 lukem */
27 1.1 lukem static int
28 1.1 lukem rewrite_cookie_cmp(
29 1.1 lukem const void *c1,
30 1.1 lukem const void *c2
31 1.1 lukem )
32 1.1 lukem {
33 1.1 lukem const struct rewrite_session *s1, *s2;
34 1.1 lukem
35 1.1 lukem s1 = ( const struct rewrite_session * )c1;
36 1.1 lukem s2 = ( const struct rewrite_session * )c2;
37 1.1 lukem
38 1.1 lukem assert( s1 != NULL );
39 1.1 lukem assert( s2 != NULL );
40 1.1 lukem assert( s1->ls_cookie != NULL );
41 1.1 lukem assert( s2->ls_cookie != NULL );
42 1.1 lukem
43 1.1 lukem return ( ( s1->ls_cookie < s2->ls_cookie ) ? -1 :
44 1.1 lukem ( ( s1->ls_cookie > s2->ls_cookie ) ? 1 : 0 ) );
45 1.1 lukem }
46 1.1 lukem
47 1.1 lukem /*
48 1.1 lukem * Duplicate cookies?
49 1.1 lukem */
50 1.1 lukem static int
51 1.1 lukem rewrite_cookie_dup(
52 1.1 lukem void *c1,
53 1.1 lukem void *c2
54 1.1 lukem )
55 1.1 lukem {
56 1.1 lukem struct rewrite_session *s1, *s2;
57 1.1 lukem
58 1.1 lukem s1 = ( struct rewrite_session * )c1;
59 1.1 lukem s2 = ( struct rewrite_session * )c2;
60 1.1 lukem
61 1.1 lukem assert( s1 != NULL );
62 1.1 lukem assert( s2 != NULL );
63 1.1 lukem assert( s1->ls_cookie != NULL );
64 1.1 lukem assert( s2->ls_cookie != NULL );
65 1.1 lukem
66 1.1 lukem assert( s1->ls_cookie != s2->ls_cookie );
67 1.1 lukem
68 1.1 lukem return ( ( s1->ls_cookie == s2->ls_cookie ) ? -1 : 0 );
69 1.1 lukem }
70 1.1 lukem
71 1.1 lukem /*
72 1.1 lukem * Inits a session
73 1.1 lukem */
74 1.1 lukem struct rewrite_session *
75 1.1 lukem rewrite_session_init(
76 1.1 lukem struct rewrite_info *info,
77 1.1 lukem const void *cookie
78 1.1 lukem )
79 1.1 lukem {
80 1.1 lukem struct rewrite_session *session, tmp;
81 1.1 lukem int rc;
82 1.1 lukem
83 1.1 lukem assert( info != NULL );
84 1.1 lukem assert( cookie != NULL );
85 1.1 lukem
86 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
87 1.1 lukem ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
88 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
89 1.1 lukem
90 1.1 lukem tmp.ls_cookie = ( void * )cookie;
91 1.1 lukem session = ( struct rewrite_session * )avl_find( info->li_cookies,
92 1.1 lukem ( caddr_t )&tmp, rewrite_cookie_cmp );
93 1.1 lukem if ( session ) {
94 1.1 lukem session->ls_count++;
95 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
96 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
97 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
98 1.1 lukem return session;
99 1.1 lukem }
100 1.1 lukem
101 1.1 lukem session = calloc( sizeof( struct rewrite_session ), 1 );
102 1.1 lukem if ( session == NULL ) {
103 1.1 lukem return NULL;
104 1.1 lukem }
105 1.1 lukem session->ls_cookie = ( void * )cookie;
106 1.1 lukem session->ls_count = 1;
107 1.1 lukem
108 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
109 1.1 lukem if ( ldap_pvt_thread_mutex_init( &session->ls_mutex ) ) {
110 1.1 lukem free( session );
111 1.1 lukem return NULL;
112 1.1 lukem }
113 1.1 lukem if ( ldap_pvt_thread_rdwr_init( &session->ls_vars_mutex ) ) {
114 1.1 lukem ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
115 1.1 lukem free( session );
116 1.1 lukem return NULL;
117 1.1 lukem }
118 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
119 1.1 lukem
120 1.1 lukem rc = avl_insert( &info->li_cookies, ( caddr_t )session,
121 1.1 lukem rewrite_cookie_cmp, rewrite_cookie_dup );
122 1.1 lukem info->li_num_cookies++;
123 1.1 lukem
124 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
125 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
126 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
127 1.1 lukem
128 1.1 lukem if ( rc != 0 ) {
129 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
130 1.1 lukem ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
131 1.1 lukem ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
132 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
133 1.1 lukem
134 1.1 lukem free( session );
135 1.1 lukem return NULL;
136 1.1 lukem }
137 1.1 lukem
138 1.1 lukem return session;
139 1.1 lukem }
140 1.1 lukem
141 1.1 lukem /*
142 1.1 lukem * Fetches a session
143 1.1 lukem */
144 1.1 lukem struct rewrite_session *
145 1.1 lukem rewrite_session_find(
146 1.1 lukem struct rewrite_info *info,
147 1.1 lukem const void *cookie
148 1.1 lukem )
149 1.1 lukem {
150 1.1 lukem struct rewrite_session *session, tmp;
151 1.1 lukem
152 1.1 lukem assert( info != NULL );
153 1.1 lukem assert( cookie != NULL );
154 1.1 lukem
155 1.1 lukem tmp.ls_cookie = ( void * )cookie;
156 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
157 1.1 lukem ldap_pvt_thread_rdwr_rlock( &info->li_cookies_mutex );
158 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
159 1.1 lukem session = ( struct rewrite_session * )avl_find( info->li_cookies,
160 1.1 lukem ( caddr_t )&tmp, rewrite_cookie_cmp );
161 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
162 1.1 lukem if ( session ) {
163 1.1 lukem ldap_pvt_thread_mutex_lock( &session->ls_mutex );
164 1.1 lukem }
165 1.1 lukem ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex );
166 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
167 1.1 lukem
168 1.1 lukem return session;
169 1.1 lukem }
170 1.1 lukem
171 1.1 lukem /*
172 1.1 lukem * Returns a session
173 1.1 lukem */
174 1.1 lukem void
175 1.1 lukem rewrite_session_return(
176 1.1 lukem struct rewrite_info *info,
177 1.1 lukem struct rewrite_session *session
178 1.1 lukem )
179 1.1 lukem {
180 1.1 lukem assert( session != NULL );
181 1.1 lukem ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
182 1.1 lukem }
183 1.1 lukem
184 1.1 lukem /*
185 1.1 lukem * Defines and inits a var with session scope
186 1.1 lukem */
187 1.1 lukem int
188 1.1 lukem rewrite_session_var_set_f(
189 1.1 lukem struct rewrite_info *info,
190 1.1 lukem const void *cookie,
191 1.1 lukem const char *name,
192 1.1 lukem const char *value,
193 1.1 lukem int flags
194 1.1 lukem )
195 1.1 lukem {
196 1.1 lukem struct rewrite_session *session;
197 1.1 lukem struct rewrite_var *var;
198 1.1 lukem
199 1.1 lukem assert( info != NULL );
200 1.1 lukem assert( cookie != NULL );
201 1.1 lukem assert( name != NULL );
202 1.1 lukem assert( value != NULL );
203 1.1 lukem
204 1.1 lukem session = rewrite_session_find( info, cookie );
205 1.1 lukem if ( session == NULL ) {
206 1.1 lukem session = rewrite_session_init( info, cookie );
207 1.1 lukem if ( session == NULL ) {
208 1.1 lukem return REWRITE_ERR;
209 1.1 lukem }
210 1.1 lukem
211 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
212 1.1 lukem ldap_pvt_thread_mutex_lock( &session->ls_mutex );
213 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
214 1.1 lukem }
215 1.1 lukem
216 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
217 1.1 lukem ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
218 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
219 1.1 lukem
220 1.1 lukem var = rewrite_var_find( session->ls_vars, name );
221 1.1 lukem if ( var != NULL ) {
222 1.1 lukem assert( var->lv_value.bv_val != NULL );
223 1.1 lukem
224 1.1 lukem (void)rewrite_var_replace( var, value, flags );
225 1.1 lukem
226 1.1 lukem } else {
227 1.1 lukem var = rewrite_var_insert_f( &session->ls_vars, name, value, flags );
228 1.1 lukem if ( var == NULL ) {
229 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
230 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
231 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
232 1.1 lukem rewrite_session_return( info, session );
233 1.1 lukem return REWRITE_ERR;
234 1.1 lukem }
235 1.1 lukem }
236 1.1 lukem
237 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
238 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
239 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
240 1.1 lukem
241 1.1 lukem rewrite_session_return( info, session );
242 1.1 lukem
243 1.1 lukem return REWRITE_SUCCESS;
244 1.1 lukem }
245 1.1 lukem
246 1.1 lukem /*
247 1.1 lukem * Gets a var with session scope
248 1.1 lukem */
249 1.1 lukem int
250 1.1 lukem rewrite_session_var_get(
251 1.1 lukem struct rewrite_info *info,
252 1.1 lukem const void *cookie,
253 1.1 lukem const char *name,
254 1.1 lukem struct berval *value
255 1.1 lukem )
256 1.1 lukem {
257 1.1 lukem struct rewrite_session *session;
258 1.1 lukem struct rewrite_var *var;
259 1.1 lukem
260 1.1 lukem assert( info != NULL );
261 1.1 lukem assert( cookie != NULL );
262 1.1 lukem assert( name != NULL );
263 1.1 lukem assert( value != NULL );
264 1.1 lukem
265 1.1 lukem value->bv_val = NULL;
266 1.1 lukem value->bv_len = 0;
267 1.1 lukem
268 1.1 lukem if ( cookie == NULL ) {
269 1.1 lukem return REWRITE_ERR;
270 1.1 lukem }
271 1.1 lukem
272 1.1 lukem session = rewrite_session_find( info, cookie );
273 1.1 lukem if ( session == NULL ) {
274 1.1 lukem return REWRITE_ERR;
275 1.1 lukem }
276 1.1 lukem
277 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
278 1.1 lukem ldap_pvt_thread_rdwr_rlock( &session->ls_vars_mutex );
279 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
280 1.1 lukem
281 1.1 lukem var = rewrite_var_find( session->ls_vars, name );
282 1.1 lukem if ( var == NULL ) {
283 1.1 lukem
284 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
285 1.1 lukem ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
286 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
287 1.1 lukem
288 1.1 lukem rewrite_session_return( info, session );
289 1.1 lukem
290 1.1 lukem return REWRITE_ERR;
291 1.1 lukem } else {
292 1.1 lukem value->bv_val = strdup( var->lv_value.bv_val );
293 1.1 lukem value->bv_len = var->lv_value.bv_len;
294 1.1 lukem }
295 1.1 lukem
296 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
297 1.1 lukem ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
298 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
299 1.1 lukem
300 1.1 lukem rewrite_session_return( info, session );
301 1.1 lukem
302 1.1 lukem return REWRITE_SUCCESS;
303 1.1 lukem }
304 1.1 lukem
305 1.1 lukem static void
306 1.1 lukem rewrite_session_clean( void *v_session )
307 1.1 lukem {
308 1.1 lukem struct rewrite_session *session = (struct rewrite_session *)v_session;
309 1.1 lukem
310 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
311 1.1 lukem ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
312 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
313 1.1 lukem
314 1.1 lukem rewrite_var_delete( session->ls_vars );
315 1.1 lukem
316 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
317 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
318 1.1 lukem ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
319 1.1 lukem ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
320 1.1 lukem ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
321 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
322 1.1 lukem }
323 1.1 lukem
324 1.1 lukem static void
325 1.1 lukem rewrite_session_free( void *v_session )
326 1.1 lukem {
327 1.1 lukem struct rewrite_session *session = (struct rewrite_session *)v_session;
328 1.1 lukem
329 1.1 lukem ldap_pvt_thread_mutex_lock( &session->ls_mutex );
330 1.1 lukem rewrite_session_clean( v_session );
331 1.1 lukem free( v_session );
332 1.1 lukem }
333 1.1 lukem
334 1.1 lukem /*
335 1.1 lukem * Deletes a session
336 1.1 lukem */
337 1.1 lukem int
338 1.1 lukem rewrite_session_delete(
339 1.1 lukem struct rewrite_info *info,
340 1.1 lukem const void *cookie
341 1.1 lukem )
342 1.1 lukem {
343 1.1 lukem struct rewrite_session *session, tmp = { 0 };
344 1.1 lukem
345 1.1 lukem assert( info != NULL );
346 1.1 lukem assert( cookie != NULL );
347 1.1 lukem
348 1.1 lukem session = rewrite_session_find( info, cookie );
349 1.1 lukem
350 1.1 lukem if ( session == NULL ) {
351 1.1 lukem return REWRITE_SUCCESS;
352 1.1 lukem }
353 1.1 lukem
354 1.1 lukem if ( --session->ls_count > 0 ) {
355 1.1 lukem rewrite_session_return( info, session );
356 1.1 lukem return REWRITE_SUCCESS;
357 1.1 lukem }
358 1.1 lukem
359 1.1 lukem rewrite_session_clean( session );
360 1.1 lukem
361 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
362 1.1 lukem ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
363 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
364 1.1 lukem
365 1.1 lukem assert( info->li_num_cookies > 0 );
366 1.1 lukem info->li_num_cookies--;
367 1.1 lukem
368 1.1 lukem /*
369 1.1 lukem * There is nothing to delete in the return value
370 1.1 lukem */
371 1.1 lukem tmp.ls_cookie = ( void * )cookie;
372 1.1 lukem avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );
373 1.1 lukem
374 1.1 lukem free( session );
375 1.1 lukem
376 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
377 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
378 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
379 1.1 lukem
380 1.1 lukem return REWRITE_SUCCESS;
381 1.1 lukem }
382 1.1 lukem
383 1.1 lukem /*
384 1.1 lukem * Destroys the cookie tree
385 1.1 lukem */
386 1.1 lukem int
387 1.1 lukem rewrite_session_destroy(
388 1.1 lukem struct rewrite_info *info
389 1.1 lukem )
390 1.1 lukem {
391 1.1 lukem int count;
392 1.1 lukem
393 1.1 lukem assert( info != NULL );
394 1.1 lukem
395 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
396 1.1 lukem ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
397 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
398 1.1 lukem
399 1.1 lukem /*
400 1.1 lukem * Should call per-session destruction routine ...
401 1.1 lukem */
402 1.1 lukem
403 1.1 lukem count = avl_free( info->li_cookies, rewrite_session_free );
404 1.1 lukem info->li_cookies = NULL;
405 1.1 lukem
406 1.1 lukem #if 0
407 1.1 lukem fprintf( stderr, "count = %d; num_cookies = %d\n",
408 1.1 lukem count, info->li_num_cookies );
409 1.1 lukem #endif
410 1.1 lukem
411 1.1 lukem assert( count == info->li_num_cookies );
412 1.1 lukem info->li_num_cookies = 0;
413 1.1 lukem
414 1.1 lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
415 1.1 lukem ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
416 1.1 lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
417 1.1 lukem
418 1.1 lukem return REWRITE_SUCCESS;
419 1.1 lukem }
420 1.1 lukem
421