Back to index

openldap  2.4.31
session.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2000-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* ACKNOWLEDGEMENT:
00016  * This work was initially developed by Pierangelo Masarati for
00017  * inclusion in OpenLDAP Software.
00018  */
00019 
00020 #include <portable.h>
00021 
00022 #include "rewrite-int.h"
00023 
00024 /*
00025  * Compares two cookies
00026  */
00027 static int
00028 rewrite_cookie_cmp(
00029                 const void *c1,
00030                 const void *c2
00031 )
00032 {
00033        const struct rewrite_session *s1, *s2;
00034 
00035        s1 = ( const struct rewrite_session * )c1;
00036        s2 = ( const struct rewrite_session * )c2;
00037 
00038        assert( s1 != NULL );
00039        assert( s2 != NULL );
00040        assert( s1->ls_cookie != NULL );
00041        assert( s2->ls_cookie != NULL );
00042 
00043         return ( ( s1->ls_cookie < s2->ls_cookie ) ? -1 :
00044                      ( ( s1->ls_cookie > s2->ls_cookie ) ? 1 : 0 ) );
00045 }
00046 
00047 /*
00048  * Duplicate cookies?
00049  */
00050 static int
00051 rewrite_cookie_dup(
00052                 void *c1,
00053                 void *c2
00054 )
00055 {
00056        struct rewrite_session *s1, *s2;
00057 
00058        s1 = ( struct rewrite_session * )c1;
00059        s2 = ( struct rewrite_session * )c2;
00060        
00061        assert( s1 != NULL );
00062        assert( s2 != NULL );
00063        assert( s1->ls_cookie != NULL );
00064        assert( s2->ls_cookie != NULL );
00065        
00066        assert( s1->ls_cookie != s2->ls_cookie );
00067        
00068         return ( ( s1->ls_cookie == s2->ls_cookie ) ? -1 : 0 );
00069 }
00070 
00071 /*
00072  * Inits a session
00073  */
00074 struct rewrite_session *
00075 rewrite_session_init(
00076               struct rewrite_info *info,
00077               const void *cookie
00078 )
00079 {
00080        struct rewrite_session      *session, tmp;
00081        int                  rc;
00082 
00083        assert( info != NULL );
00084        assert( cookie != NULL );
00085 
00086 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00087        ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
00088 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00089 
00090        tmp.ls_cookie = ( void * )cookie;
00091        session = ( struct rewrite_session * )avl_find( info->li_cookies, 
00092                      ( caddr_t )&tmp, rewrite_cookie_cmp );
00093        if ( session ) {
00094               session->ls_count++;
00095 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00096               ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
00097 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00098               return session;
00099        }
00100               
00101        session = calloc( sizeof( struct rewrite_session ), 1 );
00102        if ( session == NULL ) {
00103               return NULL;
00104        }
00105        session->ls_cookie = ( void * )cookie;
00106        session->ls_count = 1;
00107        
00108 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00109        if ( ldap_pvt_thread_mutex_init( &session->ls_mutex ) ) {
00110               free( session );
00111               return NULL;
00112        }
00113        if ( ldap_pvt_thread_rdwr_init( &session->ls_vars_mutex ) ) {
00114               ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
00115               free( session );
00116               return NULL;
00117        }
00118 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00119 
00120        rc = avl_insert( &info->li_cookies, ( caddr_t )session,
00121                      rewrite_cookie_cmp, rewrite_cookie_dup );
00122        info->li_num_cookies++;
00123 
00124 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00125         ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
00126 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00127        
00128        if ( rc != 0 ) {
00129 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00130               ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
00131               ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
00132 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00133 
00134               free( session );
00135               return NULL;
00136        }
00137        
00138        return session;
00139 }
00140 
00141 /*
00142  * Fetches a session
00143  */
00144 struct rewrite_session *
00145 rewrite_session_find(
00146               struct rewrite_info *info,
00147               const void *cookie
00148 )
00149 {
00150        struct rewrite_session *session, tmp;
00151 
00152        assert( info != NULL );
00153        assert( cookie != NULL );
00154        
00155        tmp.ls_cookie = ( void * )cookie;
00156 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00157        ldap_pvt_thread_rdwr_rlock( &info->li_cookies_mutex );
00158 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00159        session = ( struct rewrite_session * )avl_find( info->li_cookies,
00160                      ( caddr_t )&tmp, rewrite_cookie_cmp );
00161 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00162        if ( session ) {
00163               ldap_pvt_thread_mutex_lock( &session->ls_mutex );
00164        }
00165        ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex );
00166 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00167 
00168        return session;
00169 }
00170 
00171 /*
00172  * Returns a session
00173  */
00174 void
00175 rewrite_session_return(
00176               struct rewrite_info *info,
00177               struct rewrite_session *session
00178 )
00179 {
00180        assert( session != NULL );
00181        ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
00182 }
00183 
00184 /*
00185  * Defines and inits a var with session scope
00186  */
00187 int
00188 rewrite_session_var_set_f(
00189               struct rewrite_info *info,
00190               const void *cookie,
00191               const char *name,
00192               const char *value,
00193               int flags
00194 )
00195 {
00196        struct rewrite_session *session;
00197        struct rewrite_var *var;
00198 
00199        assert( info != NULL );
00200        assert( cookie != NULL );
00201        assert( name != NULL );
00202        assert( value != NULL );
00203 
00204        session = rewrite_session_find( info, cookie );
00205        if ( session == NULL ) {
00206               session = rewrite_session_init( info, cookie );
00207               if ( session == NULL ) {
00208                      return REWRITE_ERR;
00209               }
00210 
00211 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00212               ldap_pvt_thread_mutex_lock( &session->ls_mutex );
00213 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00214        }
00215 
00216 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00217        ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
00218 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00219 
00220        var = rewrite_var_find( session->ls_vars, name );
00221        if ( var != NULL ) {
00222               assert( var->lv_value.bv_val != NULL );
00223 
00224               (void)rewrite_var_replace( var, value, flags );
00225 
00226        } else {
00227               var = rewrite_var_insert_f( &session->ls_vars, name, value, flags );
00228               if ( var == NULL ) {
00229 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00230                      ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
00231 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00232                      rewrite_session_return( info, session );
00233                      return REWRITE_ERR;
00234               }
00235        }      
00236        
00237 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00238        ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
00239 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00240 
00241        rewrite_session_return( info, session );
00242 
00243        return REWRITE_SUCCESS;
00244 }
00245 
00246 /*
00247  * Gets a var with session scope
00248  */
00249 int
00250 rewrite_session_var_get(
00251               struct rewrite_info *info,
00252               const void *cookie,
00253               const char *name,
00254               struct berval *value
00255 )
00256 {
00257        struct rewrite_session *session;
00258        struct rewrite_var *var;
00259        int rc = REWRITE_SUCCESS;
00260 
00261        assert( info != NULL );
00262        assert( cookie != NULL );
00263        assert( name != NULL );
00264        assert( value != NULL );
00265 
00266        value->bv_val = NULL;
00267        value->bv_len = 0;
00268        
00269        if ( cookie == NULL ) {
00270               return REWRITE_ERR;
00271        }
00272 
00273        session = rewrite_session_find( info, cookie );
00274        if ( session == NULL ) {
00275               return REWRITE_ERR;
00276        }
00277 
00278 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00279        ldap_pvt_thread_rdwr_rlock( &session->ls_vars_mutex );
00280 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00281        
00282        var = rewrite_var_find( session->ls_vars, name );
00283        if ( var != NULL ) {
00284               value->bv_val = strdup( var->lv_value.bv_val );
00285               value->bv_len = var->lv_value.bv_len;
00286        }
00287 
00288        if ( var == NULL || value->bv_val == NULL ) {
00289               rc = REWRITE_ERR;
00290        }
00291 
00292 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00293         ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
00294 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00295 
00296        rewrite_session_return( info, session );
00297 
00298        return rc;
00299 }
00300 
00301 static void
00302 rewrite_session_clean( void *v_session )
00303 {
00304        struct rewrite_session      *session = (struct rewrite_session *)v_session;
00305 
00306 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00307        ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
00308 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00309 
00310        rewrite_var_delete( session->ls_vars );
00311 
00312 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00313        ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
00314        ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
00315        ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
00316        ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
00317 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00318 }
00319 
00320 static void
00321 rewrite_session_free( void *v_session )
00322 {
00323        struct rewrite_session      *session = (struct rewrite_session *)v_session;
00324 
00325        ldap_pvt_thread_mutex_lock( &session->ls_mutex );
00326        rewrite_session_clean( v_session );
00327        free( v_session );
00328 }
00329 
00330 /*
00331  * Deletes a session
00332  */
00333 int
00334 rewrite_session_delete(
00335               struct rewrite_info *info,
00336               const void *cookie
00337 )
00338 {
00339        struct rewrite_session *session, tmp = { 0 };
00340 
00341        assert( info != NULL );
00342        assert( cookie != NULL );
00343 
00344        session = rewrite_session_find( info, cookie );
00345 
00346        if ( session == NULL ) {
00347               return REWRITE_SUCCESS;
00348        }
00349 
00350        if ( --session->ls_count > 0 ) {
00351               rewrite_session_return( info, session );
00352               return REWRITE_SUCCESS;
00353        }
00354 
00355        rewrite_session_clean( session );
00356 
00357 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00358        ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
00359 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00360 
00361        assert( info->li_num_cookies > 0 );
00362        info->li_num_cookies--;
00363        
00364        /*
00365         * There is nothing to delete in the return value
00366         */
00367        tmp.ls_cookie = ( void * )cookie;
00368        avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );
00369 
00370        free( session );
00371 
00372 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00373        ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
00374 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00375 
00376        return REWRITE_SUCCESS;
00377 }
00378 
00379 /*
00380  * Destroys the cookie tree
00381  */
00382 int
00383 rewrite_session_destroy(
00384               struct rewrite_info *info
00385 )
00386 {
00387        int count;
00388 
00389        assert( info != NULL );
00390        
00391 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00392        ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
00393 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00394 
00395        /*
00396         * Should call per-session destruction routine ...
00397         */
00398        
00399        count = avl_free( info->li_cookies, rewrite_session_free );
00400        info->li_cookies = NULL;
00401 
00402 #if 0
00403        fprintf( stderr, "count = %d; num_cookies = %d\n", 
00404                      count, info->li_num_cookies );
00405 #endif
00406        
00407        assert( count == info->li_num_cookies );
00408        info->li_num_cookies = 0;
00409 
00410 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00411        ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
00412 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00413 
00414        return REWRITE_SUCCESS;
00415 }
00416