Back to index

openldap  2.4.31
info.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  * Global data
00026  */
00027 
00028 /*
00029  * This becomes the running context for subsequent calls to
00030  * rewrite_parse; it can be altered only by a 
00031  * rewriteContext config line or by a change in info.
00032  */
00033 struct rewrite_context *rewrite_int_curr_context = NULL;
00034 
00035 /*
00036  * Inits the info
00037  */
00038 struct rewrite_info *
00039 rewrite_info_init(
00040               int mode
00041 )
00042 {
00043        struct rewrite_info *info;
00044        struct rewrite_context *context;
00045 
00046        switch ( mode ) {
00047        case REWRITE_MODE_ERR:
00048        case REWRITE_MODE_OK:
00049        case REWRITE_MODE_COPY_INPUT:
00050        case REWRITE_MODE_USE_DEFAULT:
00051               break;
00052        default:
00053               mode = REWRITE_MODE_USE_DEFAULT;
00054               break;
00055               /* return NULL */
00056        }
00057 
00058        /*
00059         * Resets the running context for parsing ...
00060         */
00061        rewrite_int_curr_context = NULL;
00062 
00063        info = calloc( sizeof( struct rewrite_info ), 1 );
00064        if ( info == NULL ) {
00065               return NULL;
00066        }
00067 
00068        info->li_state = REWRITE_DEFAULT;
00069        info->li_max_passes = REWRITE_MAX_PASSES;
00070        info->li_max_passes_per_rule = REWRITE_MAX_PASSES;
00071        info->li_rewrite_mode = mode;
00072 
00073        /*
00074         * Add the default (empty) rule
00075         */
00076        context = rewrite_context_create( info, REWRITE_DEFAULT_CONTEXT );
00077        if ( context == NULL ) {
00078               free( info );
00079               return NULL;
00080        }
00081 
00082 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00083        if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
00084               avl_free( info->li_context, rewrite_context_free );
00085               free( info );
00086               return NULL;
00087        }
00088        if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
00089               ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
00090               avl_free( info->li_context, rewrite_context_free );
00091               free( info );
00092               return NULL;
00093        }
00094 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00095        
00096        return info;
00097 }
00098 
00099 /*
00100  * Cleans up the info structure
00101  */
00102 int
00103 rewrite_info_delete(
00104               struct rewrite_info **pinfo
00105 )
00106 {
00107        struct rewrite_info  *info;
00108 
00109        assert( pinfo != NULL );
00110        assert( *pinfo != NULL );
00111 
00112        info = *pinfo;
00113        
00114        if ( info->li_context ) {
00115               avl_free( info->li_context, rewrite_context_free );
00116        }
00117        info->li_context = NULL;
00118 
00119        if ( info->li_maps ) {
00120               avl_free( info->li_maps, rewrite_builtin_map_free );
00121        }
00122        info->li_maps = NULL;
00123 
00124        rewrite_session_destroy( info );
00125 
00126 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00127        ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
00128 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00129 
00130        rewrite_param_destroy( info );
00131        
00132 #ifdef USE_REWRITE_LDAP_PVT_THREADS
00133        ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
00134 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
00135 
00136        free( info );
00137        *pinfo = NULL;
00138 
00139        return REWRITE_SUCCESS;
00140 }
00141 
00142 /*
00143  * Rewrites a string according to context.
00144  * If the engine is off, OK is returned, but the return string will be NULL.
00145  * In case of 'unwilling to perform', UNWILLING is returned, and the
00146  * return string will also be null. The same in case of error.
00147  * Otherwise, OK is returned, and result will hold a newly allocated string
00148  * with the rewriting.
00149  * 
00150  * What to do in case of non-existing rewrite context is still an issue.
00151  * Four possibilities:
00152  *     - error, 
00153  *     - ok with NULL result, 
00154  *     - ok with copy of string as result,
00155  *     - use the default rewrite context.
00156  */
00157 int
00158 rewrite(
00159               struct rewrite_info *info,
00160               const char *rewriteContext,
00161               const char *string,
00162               char **result
00163 )
00164 {
00165        return rewrite_session( info, rewriteContext, 
00166                      string, NULL, result );
00167 }
00168 
00169 int
00170 rewrite_session(
00171               struct rewrite_info *info,
00172               const char *rewriteContext,
00173               const char *string,
00174               const void *cookie,
00175               char **result
00176 )
00177 {
00178        struct rewrite_context *context;
00179        struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
00180        int rc;
00181        
00182        assert( info != NULL );
00183        assert( rewriteContext != NULL );
00184        assert( string != NULL );
00185        assert( result != NULL );
00186 
00187        /*
00188         * cookie can be null; means: don't care about session stuff
00189         */
00190 
00191        *result = NULL;
00192        op.lo_cookie = cookie;
00193        
00194        /*
00195         * Engine not on means no failure, but explicit no rewriting
00196         */
00197        if ( info->li_state != REWRITE_ON ) {
00198               rc = REWRITE_REGEXEC_OK;
00199               goto rc_return;
00200        }
00201        
00202        /*
00203         * Undefined context means no rewriting also
00204         * (conservative, are we sure it's what we want?)
00205         */
00206        context = rewrite_context_find( info, rewriteContext );
00207        if ( context == NULL ) {
00208               switch ( info->li_rewrite_mode ) {
00209               case REWRITE_MODE_ERR:
00210                      rc = REWRITE_REGEXEC_ERR;
00211                      goto rc_return;
00212                      
00213               case REWRITE_MODE_OK:
00214                      rc = REWRITE_REGEXEC_OK;
00215                      goto rc_return;
00216 
00217               case REWRITE_MODE_COPY_INPUT:
00218                      *result = strdup( string );
00219                      rc = ( *result != NULL ) ? REWRITE_REGEXEC_OK : REWRITE_REGEXEC_ERR;
00220                      goto rc_return;
00221 
00222               case REWRITE_MODE_USE_DEFAULT:
00223                      context = rewrite_context_find( info,
00224                                    REWRITE_DEFAULT_CONTEXT );
00225                      break;
00226               }
00227        }
00228 
00229 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
00230        op.lo_string = strdup( string );
00231        if ( op.lo_string == NULL ) {
00232               rc = REWRITE_REGEXEC_ERR;
00233               goto rc_return;
00234        }
00235 #endif
00236        
00237        /*
00238         * Applies rewrite context
00239         */
00240        rc = rewrite_context_apply( info, &op, context, string, result );
00241        assert( op.lo_depth == 0 );
00242 
00243 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */      
00244        free( op.lo_string );
00245 #endif
00246        
00247        switch ( rc ) {
00248        /*
00249         * Success
00250         */
00251        case REWRITE_REGEXEC_OK:
00252        case REWRITE_REGEXEC_STOP:
00253               /*
00254                * If rewrite succeeded return OK regardless of how
00255                * the successful rewriting was obtained!
00256                */
00257               rc = REWRITE_REGEXEC_OK;
00258               break;
00259               
00260        
00261        /*
00262         * Internal or forced error, return = NULL; rc already OK.
00263         */
00264        case REWRITE_REGEXEC_UNWILLING:
00265        case REWRITE_REGEXEC_ERR:
00266               if ( *result != NULL ) {
00267                      if ( *result != string ) {
00268                             free( *result );
00269                      }
00270                      *result = NULL;
00271               }
00272 
00273        default:
00274               break;
00275        }
00276 
00277 rc_return:;
00278        if ( op.lo_vars ) {
00279               rewrite_var_delete( op.lo_vars );
00280        }
00281        
00282        return rc;
00283 }
00284