Back to index

openldap  2.4.31
Classes | Defines | Functions
rewrite-int.h File Reference
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/syslog.h>
#include <ac/regex.h>
#include <ac/socket.h>
#include <ac/unistd.h>
#include <ac/ctype.h>
#include <lber.h>
#include <ldap.h>
#include <ldap_log.h>
#include <lutil.h>
#include <avl.h>
#include <rewrite.h>
#include <ldap_pvt_thread.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  rewrite_action
struct  rewrite_map
struct  rewrite_builtin_map
struct  rewrite_submatch
struct  rewrite_subst
struct  rewrite_rule
struct  rewrite_context
struct  rewrite_session
struct  rewrite_var
struct  rewrite_op
struct  rewrite_info
union  rewrite_map.lm_union

Defines

#define LDAP_DEFINE_LDAP_DEBUG
#define malloc(x)   ber_memalloc(x)
#define calloc(x, y)   ber_memcalloc(x,y)
#define realloc(x, y)   ber_memrealloc(x,y)
#define free(x)   ber_memfree(x)
#define strdup(x)   ber_strdup(x)
#define USE_REWRITE_LDAP_PVT_THREADS
#define REWRITE_MAX_MATCH   11 /* 0: overall string; 1-9: submatches */
#define REWRITE_MAX_PASSES   100
#define REWRITE_SUBMATCH_ESCAPE_ORIG   '%'
#define REWRITE_SUBMATCH_ESCAPE   '$'
#define IS_REWRITE_SUBMATCH_ESCAPE(c)   ((c) == REWRITE_SUBMATCH_ESCAPE || (c) == REWRITE_SUBMATCH_ESCAPE_ORIG)
#define REWRITE_FLAG_HONORCASE   'C'
#define REWRITE_FLAG_BASICREGEX   'R'
#define REWRITE_FLAG_EXECONCE   ':'
#define REWRITE_FLAG_STOP   '@'
#define REWRITE_FLAG_UNWILLING   '#'
#define REWRITE_FLAG_GOTO   'G' /* requires an arg */
#define REWRITE_FLAG_USER   'U' /* requires an arg */
#define REWRITE_FLAG_MAX_PASSES   'M' /* requires an arg */
#define REWRITE_FLAG_IGNORE_ERR   'I'
#define REWRITE_OPERATOR_SUBCONTEXT   '>'
#define REWRITE_OPERATOR_COMMAND   '|'
#define REWRITE_OPERATOR_VARIABLE_SET   '&'
#define REWRITE_OPERATOR_VARIABLE_GET   '*'
#define REWRITE_OPERATOR_PARAM_GET   '$'
#define REWRITE_ACTION_STOP   0x0001
#define REWRITE_ACTION_UNWILLING   0x0002
#define REWRITE_ACTION_GOTO   0x0003
#define REWRITE_ACTION_IGNORE_ERR   0x0004
#define REWRITE_ACTION_USER   0x0005
#define REWRITE_MAP_XFILEMAP   0x0001 /* Rough implementation! */
#define REWRITE_MAP_XPWDMAP   0x0002 /* uid -> gecos */
#define REWRITE_MAP_XLDAPMAP   0x0003 /* Not implemented yet! */
#define REWRITE_MAP_SUBCONTEXT   0x0101
#define REWRITE_MAP_SET_OP_VAR   0x0102
#define REWRITE_MAP_SETW_OP_VAR   0x0103
#define REWRITE_MAP_GET_OP_VAR   0x0104
#define REWRITE_MAP_SET_SESN_VAR   0x0105
#define REWRITE_MAP_SETW_SESN_VAR   0x0106
#define REWRITE_MAP_GET_SESN_VAR   0x0107
#define REWRITE_MAP_GET_PARAM   0x0108
#define REWRITE_MAP_BUILTIN   0x0109
#define lm_args   lm_union._lm_args
#define lm_subst   lm_union._lm_subst
#define REWRITE_BUILTIN_MAP   0x0200
#define REWRITE_SUBMATCH_ASIS   0x0000
#define REWRITE_SUBMATCH_XMAP   0x0001
#define REWRITE_SUBMATCH_MAP_W_ARG   0x0002
#define REWRITE_REGEX_ICASE   REG_ICASE
#define REWRITE_REGEX_EXTENDED   REG_EXTENDED
#define REWRITE_RECURSE   0x0001
#define REWRITE_EXEC_ONCE   0x0002
#define REWRITE_MAXPASSES   100
#define rewrite_var_insert(tree, name, value)
#define rewrite_var_set(tree, name, value, insert)

Functions

 LDAP_REWRITE_V (struct rewrite_context *) rewrite_int_curr_context
 rewrite_map_parse (struct rewrite_info *info, const char *s, const char **end)
 rewrite_xmap_parse (struct rewrite_info *info, const char *s, const char **end)
 rewrite_map_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_map *map, struct berval *key, struct berval *val)
 rewrite_xmap_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_map *map, struct berval *key, struct berval *val)
 rewrite_map_destroy (struct rewrite_map **map)
 rewrite_xmap_destroy (struct rewrite_map **map)
 rewrite_builtin_map_free (void *map)
 rewrite_subst_compile (struct rewrite_info *info, const char *result)
 rewrite_subst_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_subst *subst, const char *string, const regmatch_t *match, struct berval *val)
 rewrite_subst_destroy (struct rewrite_subst **subst)
 rewrite_rule_compile (struct rewrite_info *info, struct rewrite_context *context, const char *pattern, const char *result, const char *flagstring)
 rewrite_rule_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_rule *rule, const char *string, char **result)
 rewrite_rule_destroy (struct rewrite_rule **rule)
 rewrite_session_find (struct rewrite_info *info, const void *cookie)
 rewrite_session_var_set_f (struct rewrite_info *info, const void *cookie, const char *name, const char *value, int flags)
 rewrite_session_var_get (struct rewrite_info *info, const void *cookie, const char *name, struct berval *val)
 rewrite_session_delete (struct rewrite_info *info, const void *cookie)
 rewrite_session_destroy (struct rewrite_info *info)
 rewrite_var_find (Avlnode *tree, const char *name)
 rewrite_var_replace (struct rewrite_var *var, const char *value, int flags)
 rewrite_var_insert_f (Avlnode **tree, const char *name, const char *value, int flags)
 rewrite_var_set_f (Avlnode **tree, const char *name, const char *value, int flags)
 rewrite_var_delete (Avlnode *tree)
 rewrite_context_find (struct rewrite_info *info, const char *rewriteContext)
 rewrite_context_create (struct rewrite_info *info, const char *rewriteContext)
 rewrite_context_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_context *context, const char *string, char **result)
 rewrite_context_destroy (struct rewrite_context **context)
 rewrite_context_free (void *tmp)

Class Documentation

struct rewrite_action

Definition at line 106 of file rewrite-int.h.

Collaboration diagram for rewrite_action:
Class Members
void * la_args
struct rewrite_action * la_next
int la_type
struct rewrite_map

Definition at line 121 of file rewrite-int.h.

Class Members
void * lm_data
ldap_pvt_thread_mutex_t lm_mutex
char * lm_name
int lm_type
union rewrite_map lm_union
struct rewrite_builtin_map

Definition at line 167 of file rewrite-int.h.

Collaboration diagram for rewrite_builtin_map:
Class Members
const rewrite_mapper * lb_mapper
ldap_pvt_thread_mutex_t lb_mutex
char * lb_name
void * lb_private
int lb_type
struct rewrite_submatch

Definition at line 182 of file rewrite-int.h.

Collaboration diagram for rewrite_submatch:
Class Members
struct rewrite_map * ls_map
int ls_submatch
int ls_type
struct rewrite_subst

Definition at line 200 of file rewrite-int.h.

Collaboration diagram for rewrite_subst:
Class Members
int lt_num_submatch
struct rewrite_submatch * lt_submatch
struct berval * lt_subs
size_t lt_subs_len
struct rewrite_rule

Definition at line 211 of file rewrite-int.h.

Collaboration diagram for rewrite_rule:
Class Members
struct rewrite_action * lr_action
int lr_flags
char * lr_flagstring
int lr_max_passes
int lr_mode
struct rewrite_rule * lr_next
char * lr_pattern
struct rewrite_rule * lr_prev
regex_t lr_regex
struct rewrite_subst * lr_subst
char * lr_subststring
struct rewrite_context

Definition at line 243 of file rewrite-int.h.

Collaboration diagram for rewrite_context:
Class Members
struct rewrite_context * lc_alias
char * lc_name
struct rewrite_rule * lc_rule
struct rewrite_session

Definition at line 252 of file rewrite-int.h.

Collaboration diagram for rewrite_session:
Class Members
void * ls_cookie
int ls_count
ldap_pvt_thread_mutex_t ls_mutex
Avlnode * ls_vars
ldap_pvt_thread_rdwr_t ls_vars_mutex
struct rewrite_var

Definition at line 265 of file rewrite-int.h.

Class Members
int lv_flags
char * lv_name
struct rewrite_op

Definition at line 274 of file rewrite-int.h.

Class Members
const void * lo_cookie
int lo_depth
int lo_num_passes
char * lo_result
Avlnode * lo_vars
struct rewrite_info

Definition at line 293 of file rewrite-int.h.

Collaboration diagram for rewrite_info:
Class Members
Avlnode * li_context
Avlnode * li_cookies
ldap_pvt_thread_rdwr_t li_cookies_mutex
Avlnode * li_maps
int li_max_passes
int li_max_passes_per_rule
int li_num_cookies
Avlnode * li_params
ldap_pvt_thread_rdwr_t li_params_mutex
int li_rewrite_mode
int li_state
union rewrite_map.lm_union

Definition at line 152 of file rewrite-int.h.

Class Members
void * _lm_args
struct rewrite_subst * _lm_subst

Define Documentation

#define calloc (   x,
 
)    ber_memcalloc(x,y)

Definition at line 44 of file rewrite-int.h.

#define free (   x)    ber_memfree(x)

Definition at line 46 of file rewrite-int.h.

Definition at line 68 of file rewrite-int.h.

Definition at line 36 of file rewrite-int.h.

#define lm_args   lm_union._lm_args

Definition at line 156 of file rewrite-int.h.

#define lm_subst   lm_union._lm_subst

Definition at line 157 of file rewrite-int.h.

#define malloc (   x)    ber_memalloc(x)

Definition at line 43 of file rewrite-int.h.

#define realloc (   x,
 
)    ber_memrealloc(x,y)

Definition at line 45 of file rewrite-int.h.

#define REWRITE_ACTION_GOTO   0x0003

Definition at line 111 of file rewrite-int.h.

#define REWRITE_ACTION_IGNORE_ERR   0x0004

Definition at line 112 of file rewrite-int.h.

#define REWRITE_ACTION_STOP   0x0001

Definition at line 109 of file rewrite-int.h.

#define REWRITE_ACTION_UNWILLING   0x0002

Definition at line 110 of file rewrite-int.h.

#define REWRITE_ACTION_USER   0x0005

Definition at line 113 of file rewrite-int.h.

#define REWRITE_BUILTIN_MAP   0x0200

Definition at line 168 of file rewrite-int.h.

#define REWRITE_EXEC_ONCE   0x0002

Definition at line 233 of file rewrite-int.h.

#define REWRITE_FLAG_BASICREGEX   'R'

Definition at line 76 of file rewrite-int.h.

#define REWRITE_FLAG_EXECONCE   ':'

Definition at line 81 of file rewrite-int.h.

#define REWRITE_FLAG_GOTO   'G' /* requires an arg */

Definition at line 84 of file rewrite-int.h.

#define REWRITE_FLAG_HONORCASE   'C'

Definition at line 75 of file rewrite-int.h.

#define REWRITE_FLAG_IGNORE_ERR   'I'

Definition at line 87 of file rewrite-int.h.

#define REWRITE_FLAG_MAX_PASSES   'M' /* requires an arg */

Definition at line 86 of file rewrite-int.h.

#define REWRITE_FLAG_STOP   '@'

Definition at line 82 of file rewrite-int.h.

#define REWRITE_FLAG_UNWILLING   '#'

Definition at line 83 of file rewrite-int.h.

#define REWRITE_FLAG_USER   'U' /* requires an arg */

Definition at line 85 of file rewrite-int.h.

#define REWRITE_MAP_BUILTIN   0x0109

Definition at line 142 of file rewrite-int.h.

#define REWRITE_MAP_GET_OP_VAR   0x0104

Definition at line 137 of file rewrite-int.h.

#define REWRITE_MAP_GET_PARAM   0x0108

Definition at line 141 of file rewrite-int.h.

#define REWRITE_MAP_GET_SESN_VAR   0x0107

Definition at line 140 of file rewrite-int.h.

#define REWRITE_MAP_SET_OP_VAR   0x0102

Definition at line 135 of file rewrite-int.h.

#define REWRITE_MAP_SET_SESN_VAR   0x0105

Definition at line 138 of file rewrite-int.h.

#define REWRITE_MAP_SETW_OP_VAR   0x0103

Definition at line 136 of file rewrite-int.h.

#define REWRITE_MAP_SETW_SESN_VAR   0x0106

Definition at line 139 of file rewrite-int.h.

#define REWRITE_MAP_SUBCONTEXT   0x0101

Definition at line 133 of file rewrite-int.h.

#define REWRITE_MAP_XFILEMAP   0x0001 /* Rough implementation! */

Definition at line 126 of file rewrite-int.h.

#define REWRITE_MAP_XLDAPMAP   0x0003 /* Not implemented yet! */

Definition at line 128 of file rewrite-int.h.

#define REWRITE_MAP_XPWDMAP   0x0002 /* uid -> gecos */

Definition at line 127 of file rewrite-int.h.

#define REWRITE_MAX_MATCH   11 /* 0: overall string; 1-9: submatches */

Definition at line 58 of file rewrite-int.h.

#define REWRITE_MAX_PASSES   100

Definition at line 59 of file rewrite-int.h.

#define REWRITE_MAXPASSES   100

Definition at line 319 of file rewrite-int.h.

#define REWRITE_OPERATOR_COMMAND   '|'

Definition at line 93 of file rewrite-int.h.

#define REWRITE_OPERATOR_PARAM_GET   '$'

Definition at line 96 of file rewrite-int.h.

#define REWRITE_OPERATOR_SUBCONTEXT   '>'

Definition at line 92 of file rewrite-int.h.

Definition at line 95 of file rewrite-int.h.

Definition at line 94 of file rewrite-int.h.

#define REWRITE_RECURSE   0x0001

Definition at line 232 of file rewrite-int.h.

#define REWRITE_REGEX_EXTENDED   REG_EXTENDED

Definition at line 229 of file rewrite-int.h.

#define REWRITE_REGEX_ICASE   REG_ICASE

Definition at line 228 of file rewrite-int.h.

#define REWRITE_SUBMATCH_ASIS   0x0000

Definition at line 183 of file rewrite-int.h.

#define REWRITE_SUBMATCH_ESCAPE   '$'

Definition at line 67 of file rewrite-int.h.

#define REWRITE_SUBMATCH_ESCAPE_ORIG   '%'

Definition at line 66 of file rewrite-int.h.

#define REWRITE_SUBMATCH_MAP_W_ARG   0x0002

Definition at line 185 of file rewrite-int.h.

#define REWRITE_SUBMATCH_XMAP   0x0001

Definition at line 184 of file rewrite-int.h.

#define rewrite_var_insert (   tree,
  name,
  value 
)
#define rewrite_var_set (   tree,
  name,
  value,
  insert 
)
#define strdup (   x)    ber_strdup(x)

Definition at line 48 of file rewrite-int.h.

Definition at line 51 of file rewrite-int.h.


Function Documentation

Definition at line 478 of file map.c.

{
       struct rewrite_builtin_map *map = ( struct rewrite_builtin_map * )tmp;

       assert( map != NULL );

       if ( map->lb_mapper && map->lb_mapper->rm_destroy )
              map->lb_mapper->rm_destroy( map->lb_private );

       free( map->lb_name );
       free( map );
}

Here is the caller graph for this function:

rewrite_context_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_context context,
const char *  string,
char **  result 
)

Definition at line 198 of file context.c.

{
       struct rewrite_rule *rule;
       char *s, *res = NULL;
       int return_code = REWRITE_REGEXEC_OK;
       
       assert( info != NULL );
       assert( op != NULL );
       assert( context != NULL );
       assert( context->lc_rule != NULL );
       assert( string != NULL );
       assert( result != NULL );

       op->lo_depth++;

       Debug( LDAP_DEBUG_TRACE, "==> rewrite_context_apply"
                     " [depth=%d] string='%s'\n",
                     op->lo_depth, string, 0 );
       assert( op->lo_depth > 0 );
       
       s = (char *)string;
       
       for ( rule = context->lc_rule->lr_next;
                     rule != NULL && op->lo_num_passes < info->li_max_passes;
                     rule = rule->lr_next, op->lo_num_passes++ ) {
              int rc;
              
              /*
               * Apply a single rule
               */
              rc = rewrite_rule_apply( info, op, rule, s, &res );
              
              /*
               * A rule may return:
               *     OK            with result != NULL if matched
               *     ERR           if anything was wrong
               *     UNWILLING     if the server should drop the request
               * the latter case in honored immediately;
               * the other two may require some special actions to take
               * place.
               */
              switch ( rc ) {
                     
              case REWRITE_REGEXEC_ERR:
                     Debug( LDAP_DEBUG_ANY, "==> rewrite_context_apply"
                                   " error ...\n", 0, 0, 0);

                     /*
                      * Checks for special actions to be taken
                      * in case of error ...
                      */
                     if ( rule->lr_action != NULL ) {
                            struct rewrite_action *action;
                            int do_continue = 0;
                            
                            for ( action = rule->lr_action;
                                          action != NULL;
                                          action = action->la_next ) {
                                   switch ( action->la_type ) {
                                   
                                   /*
                                    * This action takes precedence
                                    * over the others in case of failure
                                    */
                                   case REWRITE_ACTION_IGNORE_ERR:
                                          Debug( LDAP_DEBUG_ANY,
                                   "==> rewrite_context_apply"
                                   " ignoring error ...\n", 0, 0, 0 );
                                          do_continue = 1;
                                          break;

                                   /*
                                    * Goto is honored only if it comes
                                    * after ignore error
                                    */
                                   case REWRITE_ACTION_GOTO:
                                          if ( do_continue ) {
                                                 rule = rewrite_action_goto( action, rule );
                                                 if ( rule == NULL ) {
                                                        return_code = REWRITE_REGEXEC_ERR;
                                                        goto rc_end_of_context;
                                                 }
                                          }
                                          break;

                                   /*
                                    * Other actions are ignored
                                    */
                                   default:
                                          break;
                                   }
                            }

                            if ( do_continue ) {
                                   if ( rule->lr_next == NULL ) {
                                          res = s;
                                   }
                                   goto rc_continue;
                            }
                     }

                     /* 
                      * Default behavior is to bail out ...
                      */
                     return_code = REWRITE_REGEXEC_ERR;
                     goto rc_end_of_context;
              
              /*
               * OK means there were no errors or special return codes;
               * if res is defined, it means the rule matched and we
               * got a sucessful rewriting
               */
              case REWRITE_REGEXEC_OK:

                     /*
                      * It matched! Check for actions ...
                      */
                     if ( res != NULL ) {
                            struct rewrite_action *action;
                            
                            if ( s != string && s != res ) {
                                   free( s );
                            }
                            s = res;

                            for ( action = rule->lr_action;
                                          action != NULL;
                                          action = action->la_next ) {

                                   switch ( action->la_type ) {

                                   /*
                                    * This ends the rewrite context
                                    * successfully
                                    */
                                   case REWRITE_ACTION_STOP:
                                          goto rc_end_of_context;
                                   
                                   /*
                                    * This instructs the server to return
                                    * an `unwilling to perform' error
                                    * message
                                    */
                                   case REWRITE_ACTION_UNWILLING:
                                          return_code = REWRITE_REGEXEC_UNWILLING;
                                          goto rc_end_of_context;
                                   
                                   /*
                                    * This causes the processing to
                                    * jump n rules back and forth
                                    */
                                   case REWRITE_ACTION_GOTO:
                                          rule = rewrite_action_goto( action, rule );
                                          if ( rule == NULL ) {
                                                 return_code = REWRITE_REGEXEC_ERR;
                                                 goto rc_end_of_context;
                                          }
                                          break;

                                   /*
                                    * This ends the rewrite context
                                    * and returns a user-defined
                                    * error code
                                    */
                                   case REWRITE_ACTION_USER:
                                          return_code = ((int *)action->la_args)[ 0 ];
                                          goto rc_end_of_context;
                                   
                                   default:
                                          /* ... */
                                          break;
                                   }
                            }

                     /*
                      * If result was OK and string didn't match,
                      * in case of last rule we need to set the
                      * result back to the string
                      */
                     } else if ( rule->lr_next == NULL ) {
                            res = s;
                     }
                     
                     break;

              /*
               * A STOP has propagated ...
               */
              case REWRITE_REGEXEC_STOP:
                     goto rc_end_of_context;

              /*
               * This will instruct the server to return
               * an `unwilling to perform' error message
               */
              case REWRITE_REGEXEC_UNWILLING:
                     return_code = REWRITE_REGEXEC_UNWILLING;
                     goto rc_end_of_context;

              /*
               * A user-defined error code has propagated ...
               */
              default:
                     assert( rc >= REWRITE_REGEXEC_USER );
                     goto rc_end_of_context;

              }
              
rc_continue:; /* sent here by actions that require to continue */

       }

rc_end_of_context:;
       *result = res;

       Debug( LDAP_DEBUG_TRACE, "==> rewrite_context_apply"
                     " [depth=%d] res={%d,'%s'}\n",
                     op->lo_depth, return_code, ( res ? res : "NULL" ) );

       assert( op->lo_depth > 0 );
       op->lo_depth--;

       return return_code;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_context_create ( struct rewrite_info info,
const char *  rewriteContext 
) [read]

Definition at line 108 of file context.c.

{
       struct rewrite_context *context;
       int rc;

       assert( info != NULL );
       assert( rewriteContext != NULL );
       
       context = calloc( sizeof( struct rewrite_context ), 1 );
       if ( context == NULL ) {
              return NULL;
       }
       
       /*
        * Context name
        */
       context->lc_name = strdup( rewriteContext );
       if ( context->lc_name == NULL ) {
              free( context );
              return NULL;
       }

       /*
        * The first, empty rule
        */
       context->lc_rule = calloc( sizeof( struct rewrite_rule ), 1 );
       if ( context->lc_rule == NULL ) {
              free( context->lc_name );
              free( context );
              return NULL;
       }
       memset( context->lc_rule, 0, sizeof( struct rewrite_rule ) );
       
       /*
        * Add context to tree
        */
       rc = avl_insert( &info->li_context, (caddr_t)context,
                     rewrite_context_cmp, rewrite_context_dup );
       if ( rc == -1 ) {
              free( context->lc_rule );
              free( context->lc_name );
              free( context );
              return NULL;
       }

       return context;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_context_destroy ( struct rewrite_context **  context)

Definition at line 442 of file context.c.

{
       struct rewrite_context *context;
       struct rewrite_rule *r;

       assert( pcontext != NULL );
       assert( *pcontext != NULL );

       context = *pcontext;

       assert( context->lc_rule != NULL );

       for ( r = context->lc_rule->lr_next; r; ) {
              struct rewrite_rule *cr = r;

              r = r->lr_next;
              rewrite_rule_destroy( &cr );
       }

       free( context->lc_rule );
       context->lc_rule = NULL;

       assert( context->lc_name != NULL );
       free( context->lc_name );
       context->lc_name = NULL;

       free( context );
       *pcontext = NULL;
       
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_context_find ( struct rewrite_info info,
const char *  rewriteContext 
) [read]

Definition at line 74 of file context.c.

{
       struct rewrite_context *context, c;

       assert( info != NULL );
       assert( rewriteContext != NULL );

       /*
        * Fetches the required rewrite context
        */
       c.lc_name = (char *)rewriteContext;
       context = (struct rewrite_context *)avl_find( info->li_context, 
                     (caddr_t)&c, rewrite_context_cmp );
       if ( context == NULL ) {
              return NULL;
       }

       /*
        * De-aliases the context if required
        */
       if ( context->lc_alias ) {
              return context->lc_alias;
       }

       return context;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 430 of file context.c.

{
       struct rewrite_context *context = (struct rewrite_context *)tmp;

       assert( tmp != NULL );

       rewrite_context_destroy( &context );
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_map_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_map map,
struct berval key,
struct berval val 
)

Definition at line 359 of file map.c.

{
       int rc = REWRITE_SUCCESS;

       assert( info != NULL );
       assert( op != NULL );
       assert( map != NULL );
       assert( key != NULL );
       assert( val != NULL );

       val->bv_val = NULL;
       val->bv_len = 0;
       
       switch ( map->lm_type ) {
       case REWRITE_MAP_SUBCONTEXT:
              rc = rewrite_context_apply( info, op, 
                            ( struct rewrite_context * )map->lm_data,
                            key->bv_val, &val->bv_val );
              if ( val->bv_val != NULL ) {
                     if ( val->bv_val == key->bv_val ) {
                            val->bv_len = key->bv_len;
                            key->bv_val = NULL;
                     } else {
                            val->bv_len = strlen( val->bv_val );
                     }
              }
              break;

       case REWRITE_MAP_SET_OP_VAR:
       case REWRITE_MAP_SETW_OP_VAR:
              rc = rewrite_var_set( &op->lo_vars, map->lm_name,
                            key->bv_val, 1 )
                     ? REWRITE_SUCCESS : REWRITE_ERR;
              if ( rc == REWRITE_SUCCESS ) {
                     if ( map->lm_type == REWRITE_MAP_SET_OP_VAR ) {
                            val->bv_val = strdup( "" );
                     } else {
                            val->bv_val = strdup( key->bv_val );
                            val->bv_len = key->bv_len;
                     }
                     if ( val->bv_val == NULL ) {
                            rc = REWRITE_ERR;
                     }
              }
              break;
       
       case REWRITE_MAP_GET_OP_VAR: {
              struct rewrite_var *var;

              var = rewrite_var_find( op->lo_vars, map->lm_name );
              if ( var == NULL ) {
                     rc = REWRITE_ERR;
              } else {
                     val->bv_val = strdup( var->lv_value.bv_val );
                     val->bv_len = var->lv_value.bv_len;
                     if ( val->bv_val == NULL ) {
                            rc = REWRITE_ERR;
                     }
              }
              break; 
       }

       case REWRITE_MAP_SET_SESN_VAR:
       case REWRITE_MAP_SETW_SESN_VAR:
              if ( op->lo_cookie == NULL ) {
                     rc = REWRITE_ERR;
                     break;
              }
              rc = rewrite_session_var_set( info, op->lo_cookie, 
                            map->lm_name, key->bv_val );
              if ( rc == REWRITE_SUCCESS ) {
                     if ( map->lm_type == REWRITE_MAP_SET_SESN_VAR ) {
                            val->bv_val = strdup( "" );
                     } else {
                            val->bv_val = strdup( key->bv_val );
                            val->bv_len = key->bv_len;
                     }
                     if ( val->bv_val == NULL ) {
                            rc = REWRITE_ERR;
                     }
              }
              break;

       case REWRITE_MAP_GET_SESN_VAR:
              rc = rewrite_session_var_get( info, op->lo_cookie,
                            map->lm_name, val );
              break;        

       case REWRITE_MAP_GET_PARAM:
              rc = rewrite_param_get( info, map->lm_name, val );
              break;

       case REWRITE_MAP_BUILTIN: {
              struct rewrite_builtin_map *bmap = map->lm_data;

              if ( bmap->lb_mapper && bmap->lb_mapper->rm_apply )
                     rc = bmap->lb_mapper->rm_apply( bmap->lb_private, key->bv_val,
                            val );
              else
                     rc = REWRITE_ERR;
                     break;
              break;
       }

       default:
              rc = REWRITE_ERR;
              break;
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_map_destroy ( struct rewrite_map **  map)

Definition at line 494 of file map.c.

{
       struct rewrite_map *map;
       
       assert( pmap != NULL );
       assert( *pmap != NULL );

       map = *pmap;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_mutex_lock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       if ( map->lm_name ) {
              free( map->lm_name );
              map->lm_name = NULL;
       }

       if ( map->lm_subst ) {
              rewrite_subst_destroy( &map->lm_subst );
       }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
       ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       free( map );
       *pmap = NULL;
       
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_map_parse ( struct rewrite_info info,
const char *  s,
const char **  end 
) [read]

Definition at line 36 of file map.c.

{
       struct rewrite_map *map = NULL;
       struct rewrite_subst *subst = NULL;
       char *s, *begin = NULL, *end;
       const char *p;
       int l, cnt, mtx = 0, rc = 0;

       assert( info != NULL );
       assert( string != NULL );
       assert( currpos != NULL );

       *currpos = NULL;

       /*
        * Go to the end of the map invocation (the right closing brace)
        */
       for ( p = string, cnt = 1; p[ 0 ] != '\0' && cnt > 0; p++ ) {
              if ( IS_REWRITE_SUBMATCH_ESCAPE( p[ 0 ] ) ) {
                     /*
                      * '%' marks the beginning of a new map
                      */
                     if ( p[ 1 ] == '{' ) {
                            cnt++;
                     /*
                      * '%' followed by a digit may mark the beginning
                      * of an old map
                      */
                     } else if ( isdigit( (unsigned char) p[ 1 ] ) && p[ 2 ] == '{' ) {
                            cnt++;
                            p++;
                     }

                     if ( p[ 1 ] != '\0' ) {
                            p++;
                     }

              } else if ( p[ 0 ] == '}' ) {
                     cnt--;
              }
       }
       if ( cnt != 0 ) {
              return NULL;
       }
       *currpos = p;
       
       /*
        * Copy the map invocation
        */
       l = p - string - 1;
       s = calloc( sizeof( char ), l + 1 );
       if ( s == NULL ) {
              return NULL;
       }
       AC_MEMCPY( s, string, l );
       s[ l ] = 0;

       /*
        * Isolate the map name (except for variable deref)
        */
       switch ( s[ 0 ] ) {
       case REWRITE_OPERATOR_VARIABLE_GET:
       case REWRITE_OPERATOR_PARAM_GET:
              break;

       default:
              begin = strchr( s, '(' );
              if ( begin == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              begin[ 0 ] = '\0';
              begin++;
              break;
       }

       /*
        * Check for special map types
        */
       p = s;
       switch ( p[ 0 ] ) {
       case REWRITE_OPERATOR_SUBCONTEXT:
       case REWRITE_OPERATOR_COMMAND:
       case REWRITE_OPERATOR_VARIABLE_SET:
       case REWRITE_OPERATOR_VARIABLE_GET:
       case REWRITE_OPERATOR_PARAM_GET:
              p++;
              break;
       }

       /*
        * Variable set and get may be repeated to indicate session-wide
        * instead of operation-wide variables
        */
       switch ( p[ 0 ] ) {
        case REWRITE_OPERATOR_VARIABLE_SET:
       case REWRITE_OPERATOR_VARIABLE_GET:
              p++;
              break;
       }

       /*
        * Variable get token can be appended to variable set to mean store
        * AND rewrite
        */
       if ( p[ 0 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
              p++;
       }
       
       /*
        * Check the syntax of the variable name
        */
       if ( !isalpha( (unsigned char) p[ 0 ] ) ) {
              rc = -1;
              goto cleanup;
       }
       for ( p++; p[ 0 ] != '\0'; p++ ) {
              if ( !isalnum( (unsigned char) p[ 0 ] ) ) {
                     rc = -1;
                     goto cleanup;
              }
       }

       /*
        * Isolate the argument of the map (except for variable deref)
        */
       switch ( s[ 0 ] ) {
       case REWRITE_OPERATOR_VARIABLE_GET:
       case REWRITE_OPERATOR_PARAM_GET:
              break;

       default:
              end = strrchr( begin, ')' );
              if ( end == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              end[ 0 ] = '\0';

              /*
               * Compile the substitution pattern of the map argument
               */
              subst = rewrite_subst_compile( info, begin );
              if ( subst == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;
       }

       /*
        * Create the map
        */
       map = calloc( sizeof( struct rewrite_map ), 1 );
       if ( map == NULL ) {
              rc = -1;
              goto cleanup;
       }
       memset( map, 0, sizeof( struct rewrite_map ) );
       
#ifdef USE_REWRITE_LDAP_PVT_THREADS
        if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
              rc = -1;
              goto cleanup;
       }
       ++mtx;
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
                     
       /*
        * No subst for variable deref
        */
       switch ( s[ 0 ] ) {
       case REWRITE_OPERATOR_VARIABLE_GET:
       case REWRITE_OPERATOR_PARAM_GET:
              break;

       default:
              map->lm_subst = subst;
              break;
       }

       /*
        * Parses special map types
        */
       switch ( s[ 0 ] ) {
       
       /*
        * Subcontext
        */
       case REWRITE_OPERATOR_SUBCONTEXT:         /* '>' */

              /*
               * Fetch the rewrite context
               * it MUST have been defined previously
               */
              map->lm_type = REWRITE_MAP_SUBCONTEXT;
              map->lm_name = strdup( s + 1 );
              if ( map->lm_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              map->lm_data = rewrite_context_find( info, s + 1 );
              if ( map->lm_data == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;

       /*
        * External command (not implemented yet)
        */
       case REWRITE_OPERATOR_COMMAND:            /* '|' */
              rc = -1;
              goto cleanup;
       
       /*
        * Variable set
        */
       case REWRITE_OPERATOR_VARIABLE_SET:       /* '&' */
              if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_SET ) {
                     if ( s[ 2 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
                            map->lm_type = REWRITE_MAP_SETW_SESN_VAR;
                            map->lm_name = strdup( s + 3 );
                     } else {
                            map->lm_type = REWRITE_MAP_SET_SESN_VAR;
                            map->lm_name = strdup( s + 2 );
                     }
              } else {
                     if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
                            map->lm_type = REWRITE_MAP_SETW_OP_VAR;
                            map->lm_name = strdup( s + 2 );
                     } else {
                            map->lm_type = REWRITE_MAP_SET_OP_VAR;
                            map->lm_name = strdup( s + 1 );
                     }
              }
              if ( map->lm_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;
       
       /*
        * Variable dereference
        */
       case REWRITE_OPERATOR_VARIABLE_GET:       /* '*' */
              if ( s[ 1 ] == REWRITE_OPERATOR_VARIABLE_GET ) {
                     map->lm_type = REWRITE_MAP_GET_SESN_VAR;
                     map->lm_name = strdup( s + 2 );
              } else {
                     map->lm_type = REWRITE_MAP_GET_OP_VAR;
                     map->lm_name = strdup( s + 1 );
              }
              if ( map->lm_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;
       
       /*
        * Parameter
        */
       case REWRITE_OPERATOR_PARAM_GET:          /* '$' */
              map->lm_type = REWRITE_MAP_GET_PARAM;
              map->lm_name = strdup( s + 1 );
              if ( map->lm_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;
       
       /*
        * Built-in map
        */
       default:
              map->lm_type = REWRITE_MAP_BUILTIN;
              map->lm_name = strdup( s );
              if ( map->lm_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              map->lm_data = rewrite_builtin_map_find( info, s );
              if ( map->lm_data == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              break;

       }

cleanup:
       free( s );
       if ( rc ) {
              if ( subst != NULL ) {
                     free( subst );
              }
              if ( map ) {
#ifdef USE_REWRITE_LDAP_PVT_THREADS
                      if ( mtx ) {
                            ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
                     }
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

                     if ( map->lm_name ) {
                            free( map->lm_name );
                            map->lm_name = NULL;
                     }
                     free( map );
                     map = NULL;
              }
       }

       return map;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_rule_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_rule rule,
const char *  string,
char **  result 
)

Definition at line 395 of file rule.c.

{
       size_t nmatch = REWRITE_MAX_MATCH;
       regmatch_t match[ REWRITE_MAX_MATCH ];

       int rc = REWRITE_SUCCESS;

       char *string;
       int strcnt = 0;
       struct berval val = { 0, NULL };

       assert( info != NULL );
       assert( op != NULL );
       assert( rule != NULL );
       assert( arg != NULL );
       assert( result != NULL );

       *result = NULL;

       string = (char *)arg;
       
       /*
        * In case recursive match is required (default)
        */
recurse:;

       Debug( LDAP_DEBUG_TRACE, "==> rewrite_rule_apply"
                     " rule='%s' string='%s' [%d pass(es)]\n", 
                     rule->lr_pattern, string, strcnt + 1 );
       
       op->lo_num_passes++;

       rc = regexec( &rule->lr_regex, string, nmatch, match, 0 );
       if ( rc != 0 ) {
              if ( *result == NULL && string != arg ) {
                     free( string );
              }

              /*
               * No match is OK; *result = NULL means no match
               */
              return REWRITE_REGEXEC_OK;
       }

       rc = rewrite_subst_apply( info, op, rule->lr_subst, string,
                     match, &val );

       *result = val.bv_val;
       val.bv_val = NULL;
       if ( string != arg ) {
              free( string );
              string = NULL;
       }

       if ( rc != REWRITE_REGEXEC_OK ) {
              return rc;
       }

       if ( ( rule->lr_mode & REWRITE_RECURSE ) == REWRITE_RECURSE 
                     && op->lo_num_passes < info->li_max_passes
                     && ++strcnt < rule->lr_max_passes ) {
              string = *result;

              goto recurse;
       }

       return REWRITE_REGEXEC_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_rule_compile ( struct rewrite_info info,
struct rewrite_context context,
const char *  pattern,
const char *  result,
const char *  flagstring 
)

Definition at line 118 of file rule.c.

{
       int flags = REWRITE_REGEX_EXTENDED | REWRITE_REGEX_ICASE;
       int mode = REWRITE_RECURSE;
       int max_passes;

       struct rewrite_rule *rule = NULL;
       struct rewrite_subst *subst = NULL;
       struct rewrite_action *action = NULL, *first_action = NULL;

       const char *p;

       assert( info != NULL );
       assert( context != NULL );
       assert( pattern != NULL );
       assert( result != NULL );
       /*
        * A null flagstring should be allowed
        */

       max_passes = info->li_max_passes_per_rule;

       /*
        * Take care of substitution string
        */
       subst = rewrite_subst_compile( info, result );
       if ( subst == NULL ) {
              return REWRITE_ERR;
       }

       /*
        * Take care of flags
        */
       for ( p = flagstring; p[ 0 ] != '\0'; p++ ) {
              switch( p[ 0 ] ) {
                     
              /*
               * REGEX flags
               */
              case REWRITE_FLAG_HONORCASE:              /* 'C' */
                     /*
                      * Honor case (default is case insensitive)
                      */
                     flags &= ~REWRITE_REGEX_ICASE;
                     break;
                     
              case REWRITE_FLAG_BASICREGEX:             /* 'R' */
                     /*
                      * Use POSIX Basic Regular Expression syntax
                      * instead of POSIX Extended Regular Expression 
                      * syntax (default)
                      */
                     flags &= ~REWRITE_REGEX_EXTENDED;
                     break;
                     
              /*
               * Execution mode flags
               */
              case REWRITE_FLAG_EXECONCE:               /* ':' */
                     /*
                      * Apply rule once only
                      */
                     mode &= ~REWRITE_RECURSE;
                     mode |= REWRITE_EXEC_ONCE;
                     break;
              
              /*
               * Special action flags
               */
              case REWRITE_FLAG_STOP:                   /* '@' */
                     /*
                      * Bail out after applying rule
                      */
                     action = calloc( sizeof( struct rewrite_action ), 1 );
                     if ( action == NULL ) {
                            goto fail;
                     }

                     action->la_type = REWRITE_ACTION_STOP;
                     break;
                     
              case REWRITE_FLAG_UNWILLING:              /* '#' */
                     /*
                      * Matching objs will be marked as gone!
                      */
                     action = calloc( sizeof( struct rewrite_action ), 1 );
                     if ( action == NULL ) {
                            goto fail;
                     }
                     
                     mode &= ~REWRITE_RECURSE;
                     mode |= REWRITE_EXEC_ONCE;
                     action->la_type = REWRITE_ACTION_UNWILLING;
                     break;

              case REWRITE_FLAG_GOTO:                          /* 'G' */
                     /*
                      * After applying rule, jump N rules
                      */

              case REWRITE_FLAG_USER: {                 /* 'U' */
                     /*
                      * After applying rule, return user-defined
                      * error code
                      */
                     char *next = NULL;
                     int *d;
                     
                     if ( p[ 1 ] != '{' ) {
                            goto fail;
                     }

                     d = malloc( sizeof( int ) );
                     if ( d == NULL ) {
                            goto fail;
                     }

                     d[ 0 ] = strtol( &p[ 2 ], &next, 0 );
                     if ( next == &p[ 2 ] || next[0] != '}' ) {
                            free( d );
                            goto fail;
                     }

                     action = calloc( sizeof( struct rewrite_action ), 1 );
                     if ( action == NULL ) {
                            free( d );
                            goto fail;
                     }
                     switch ( p[ 0 ] ) {
                     case REWRITE_FLAG_GOTO:
                            action->la_type = REWRITE_ACTION_GOTO;
                            break;

                     case REWRITE_FLAG_USER:
                            action->la_type = REWRITE_ACTION_USER;
                            break;

                     default:
                            assert(0);
                     }

                     action->la_args = (void *)d;

                     p = next;     /* p is incremented by the for ... */
              
                     break;
              }

              case REWRITE_FLAG_MAX_PASSES: {                  /* 'U' */
                     /*
                      * Set the number of max passes per rule
                      */
                     char *next = NULL;
                     
                     if ( p[ 1 ] != '{' ) {
                            goto fail;
                     }

                     max_passes = strtol( &p[ 2 ], &next, 0 );
                     if ( next == &p[ 2 ] || next[0] != '}' ) {
                            goto fail;
                     }

                     if ( max_passes < 1 ) {
                            /* FIXME: nonsense ... */
                            max_passes = 1;
                     }

                     p = next;     /* p is incremented by the for ... */
              
                     break;
              }

              case REWRITE_FLAG_IGNORE_ERR:               /* 'I' */
                     /*
                      * Ignore errors!
                      */
                     action = calloc( sizeof( struct rewrite_action ), 1 );
                     if ( action == NULL ) {
                            goto fail;
                     }
                     
                     action->la_type = REWRITE_ACTION_IGNORE_ERR;
                     break;
                     
              /*
               * Other flags ...
               */
              default:
                     /*
                      * Unimplemented feature (complain only)
                      */
                     break;
              }
              
              /*
               * Stupid way to append to a list ...
               */
              if ( action != NULL ) {
                     append_action( &first_action, action );
                     action = NULL;
              }
       }
       
       /*
        * Finally, rule allocation
        */
       rule = calloc( sizeof( struct rewrite_rule ), 1 );
       if ( rule == NULL ) {
              goto fail;
       }
       
       /*
        * REGEX compilation (luckily I don't need to take care of this ...)
        */
       if ( regcomp( &rule->lr_regex, ( char * )pattern, flags ) != 0 ) {
              goto fail;
       }
       
       /*
        * Just to remember them ...
        */
       rule->lr_pattern = strdup( pattern );
       rule->lr_subststring = strdup( result );
       rule->lr_flagstring = strdup( flagstring );
       if ( rule->lr_pattern == NULL
              || rule->lr_subststring == NULL
              || rule->lr_flagstring == NULL )
       {
              goto fail;
       }
       
       /*
        * Load compiled data into rule
        */
       rule->lr_subst = subst;

       /*
        * Set various parameters
        */
       rule->lr_flags = flags;            /* don't really need any longer ... */
       rule->lr_mode = mode;
       rule->lr_max_passes = max_passes;
       rule->lr_action = first_action;
       
       /*
        * Append rule at the end of the rewrite context
        */
       append_rule( context, rule );

       return REWRITE_SUCCESS;

fail:
       if ( rule ) {
              if ( rule->lr_pattern ) free( rule->lr_pattern );
              if ( rule->lr_subststring ) free( rule->lr_subststring );
              if ( rule->lr_flagstring ) free( rule->lr_flagstring );
              free( rule );
       }
       destroy_actions( first_action );
       free( subst );
       return REWRITE_ERR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_rule_destroy ( struct rewrite_rule **  rule)

Definition at line 471 of file rule.c.

{
       struct rewrite_rule *rule;

       assert( prule != NULL );
       assert( *prule != NULL );

       rule = *prule;

       if ( rule->lr_pattern ) {
              free( rule->lr_pattern );
              rule->lr_pattern = NULL;
       }

       if ( rule->lr_subststring ) {
              free( rule->lr_subststring );
              rule->lr_subststring = NULL;
       }

       if ( rule->lr_flagstring ) {
              free( rule->lr_flagstring );
              rule->lr_flagstring = NULL;
       }

       if ( rule->lr_subst ) {
              rewrite_subst_destroy( &rule->lr_subst );
       }

       regfree( &rule->lr_regex );

       destroy_actions( rule->lr_action );

       free( rule );
       *prule = NULL;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_session_delete ( struct rewrite_info info,
const void cookie 
)

Definition at line 334 of file session.c.

{
       struct rewrite_session *session, tmp = { 0 };

       assert( info != NULL );
       assert( cookie != NULL );

       session = rewrite_session_find( info, cookie );

       if ( session == NULL ) {
              return REWRITE_SUCCESS;
       }

       if ( --session->ls_count > 0 ) {
              rewrite_session_return( info, session );
              return REWRITE_SUCCESS;
       }

       rewrite_session_clean( session );

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       assert( info->li_num_cookies > 0 );
       info->li_num_cookies--;
       
       /*
        * There is nothing to delete in the return value
        */
       tmp.ls_cookie = ( void * )cookie;
       avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );

       free( session );

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       return REWRITE_SUCCESS;
}

Here is the call graph for this function:

Definition at line 383 of file session.c.

{
       int count;

       assert( info != NULL );
       
#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       /*
        * Should call per-session destruction routine ...
        */
       
       count = avl_free( info->li_cookies, rewrite_session_free );
       info->li_cookies = NULL;

#if 0
       fprintf( stderr, "count = %d; num_cookies = %d\n", 
                     count, info->li_num_cookies );
#endif
       
       assert( count == info->li_num_cookies );
       info->li_num_cookies = 0;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       return REWRITE_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_session_find ( struct rewrite_info info,
const void cookie 
) [read]

Definition at line 145 of file session.c.

{
       struct rewrite_session *session, tmp;

       assert( info != NULL );
       assert( cookie != NULL );
       
       tmp.ls_cookie = ( void * )cookie;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_rlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
       session = ( struct rewrite_session * )avl_find( info->li_cookies,
                     ( caddr_t )&tmp, rewrite_cookie_cmp );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
       if ( session ) {
              ldap_pvt_thread_mutex_lock( &session->ls_mutex );
       }
       ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       return session;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_session_var_get ( struct rewrite_info info,
const void cookie,
const char *  name,
struct berval val 
)

Definition at line 250 of file session.c.

{
       struct rewrite_session *session;
       struct rewrite_var *var;
       int rc = REWRITE_SUCCESS;

       assert( info != NULL );
       assert( cookie != NULL );
       assert( name != NULL );
       assert( value != NULL );

       value->bv_val = NULL;
       value->bv_len = 0;
       
       if ( cookie == NULL ) {
              return REWRITE_ERR;
       }

       session = rewrite_session_find( info, cookie );
       if ( session == NULL ) {
              return REWRITE_ERR;
       }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_rlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
       
       var = rewrite_var_find( session->ls_vars, name );
       if ( var != NULL ) {
              value->bv_val = strdup( var->lv_value.bv_val );
              value->bv_len = var->lv_value.bv_len;
       }

       if ( var == NULL || value->bv_val == NULL ) {
              rc = REWRITE_ERR;
       }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       rewrite_session_return( info, session );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_session_var_set_f ( struct rewrite_info info,
const void cookie,
const char *  name,
const char *  value,
int  flags 
)

Definition at line 188 of file session.c.

{
       struct rewrite_session *session;
       struct rewrite_var *var;

       assert( info != NULL );
       assert( cookie != NULL );
       assert( name != NULL );
       assert( value != NULL );

       session = rewrite_session_find( info, cookie );
       if ( session == NULL ) {
              session = rewrite_session_init( info, cookie );
              if ( session == NULL ) {
                     return REWRITE_ERR;
              }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_lock( &session->ls_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
       }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       var = rewrite_var_find( session->ls_vars, name );
       if ( var != NULL ) {
              assert( var->lv_value.bv_val != NULL );

              (void)rewrite_var_replace( var, value, flags );

       } else {
              var = rewrite_var_insert_f( &session->ls_vars, name, value, flags );
              if ( var == NULL ) {
#ifdef USE_REWRITE_LDAP_PVT_THREADS
                     ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
                     rewrite_session_return( info, session );
                     return REWRITE_ERR;
              }
       }      
       
#ifdef USE_REWRITE_LDAP_PVT_THREADS
       ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

       rewrite_session_return( info, session );

       return REWRITE_SUCCESS;
}

Here is the call graph for this function:

rewrite_subst_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_subst subst,
const char *  string,
const regmatch_t *  match,
struct berval val 
)

Definition at line 267 of file subst.c.

{
       struct berval *submatch = NULL;
       char *res = NULL;
       int n = 0, l, cl;
       int rc = REWRITE_REGEXEC_OK;

       assert( info != NULL );
       assert( op != NULL );
       assert( subst != NULL );
       assert( string != NULL );
       assert( match != NULL );
       assert( val != NULL );

       assert( val->bv_val == NULL );

       val->bv_val = NULL;
       val->bv_len = 0;

       /*
        * Prepare room for submatch expansion
        */
       if ( subst->lt_num_submatch > 0 ) {
              submatch = calloc( sizeof( struct berval ),
                            subst->lt_num_submatch );
              if ( submatch == NULL ) {
                     return REWRITE_REGEXEC_ERR;
              }
       }
       
       /*
        * Resolve submatches (simple subst, map expansion and so).
        */
       for ( n = 0, l = 0; n < subst->lt_num_submatch; n++ ) {
              struct berval key = { 0, NULL };

              submatch[ n ].bv_val = NULL;
              
              /*
               * Get key
               */
              switch ( subst->lt_submatch[ n ].ls_type ) {
              case REWRITE_SUBMATCH_ASIS:
              case REWRITE_SUBMATCH_XMAP:
                     rc = submatch_copy( &subst->lt_submatch[ n ],
                                   string, match, &key );
                     if ( rc != REWRITE_SUCCESS ) {
                            rc = REWRITE_REGEXEC_ERR;
                            goto cleanup;
                     }
                     break;
                     
              case REWRITE_SUBMATCH_MAP_W_ARG:
                     switch ( subst->lt_submatch[ n ].ls_map->lm_type ) {
                     case REWRITE_MAP_GET_OP_VAR:
                     case REWRITE_MAP_GET_SESN_VAR:
                     case REWRITE_MAP_GET_PARAM:
                            rc = REWRITE_SUCCESS;
                            break;

                     default:
                            rc = rewrite_subst_apply( info, op, 
                                   subst->lt_submatch[ n ].ls_map->lm_subst,
                                   string, match, &key);
                     }
                     
                     if ( rc != REWRITE_SUCCESS ) {
                            goto cleanup;
                     }
                     break;

              default:
                     Debug( LDAP_DEBUG_ANY, "Not Implemented\n", 0, 0, 0 );
                     rc = REWRITE_ERR;
                     break;
              }
              
              if ( rc != REWRITE_SUCCESS ) {
                     rc = REWRITE_REGEXEC_ERR;
                     goto cleanup;
              }

              /*
               * Resolve key
               */
              switch ( subst->lt_submatch[ n ].ls_type ) {
              case REWRITE_SUBMATCH_ASIS:
                     submatch[ n ] = key;
                     rc = REWRITE_SUCCESS;
                     break;
                     
              case REWRITE_SUBMATCH_XMAP:
                     rc = rewrite_xmap_apply( info, op,
                                   subst->lt_submatch[ n ].ls_map,
                                   &key, &submatch[ n ] );
                     free( key.bv_val );
                     key.bv_val = NULL;
                     break;
                     
              case REWRITE_SUBMATCH_MAP_W_ARG:
                     rc = rewrite_map_apply( info, op,
                                   subst->lt_submatch[ n ].ls_map,
                                   &key, &submatch[ n ] );
                     free( key.bv_val );
                     key.bv_val = NULL;
                     break;

              default:
                     /*
                      * When implemented, this might return the
                         * exit status of a rewrite context,
                         * which may include a stop, or an
                         * unwilling to perform
                         */
                     rc = REWRITE_ERR;
                     break;
              }

              if ( rc != REWRITE_SUCCESS ) {
                     rc = REWRITE_REGEXEC_ERR;
                     goto cleanup;
              }
              
              /*
                 * Increment the length of the resulting string
                 */
              l += submatch[ n ].bv_len;
       }
       
       /*
         * Alloc result buffer
         */
       l += subst->lt_subs_len;
       res = malloc( l + 1 );
       if ( res == NULL ) {
              rc = REWRITE_REGEXEC_ERR;
              goto cleanup;
       }

       /*
        * Apply submatches (possibly resolved thru maps)
        */
        for ( n = 0, cl = 0; n < subst->lt_num_submatch; n++ ) {
              if ( subst->lt_subs[ n ].bv_val != NULL ) {
                     AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val,
                                   subst->lt_subs[ n ].bv_len );
                     cl += subst->lt_subs[ n ].bv_len;
              }
              AC_MEMCPY( res + cl, submatch[ n ].bv_val, 
                            submatch[ n ].bv_len );
              cl += submatch[ n ].bv_len;
       }
       if ( subst->lt_subs[ n ].bv_val != NULL ) {
              AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val,
                            subst->lt_subs[ n ].bv_len );
              cl += subst->lt_subs[ n ].bv_len;
       }
       res[ cl ] = '\0';

       val->bv_val = res;
       val->bv_len = l;

cleanup:;
       if ( submatch ) {
              for ( ; --n >= 0; ) {
                     if ( submatch[ n ].bv_val ) {
                            free( submatch[ n ].bv_val );
                     }
              }
              free( submatch );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_subst_compile ( struct rewrite_info info,
const char *  result 
) [read]

Definition at line 28 of file subst.c.

{
       size_t subs_len;
       struct berval *subs = NULL, *tmps;
       struct rewrite_submatch *submatch = NULL;

       struct rewrite_subst *s = NULL;

       char *result, *begin, *p;
       int nsub = 0, l;

       assert( info != NULL );
       assert( str != NULL );

       result = strdup( str );
       if ( result == NULL ) {
              return NULL;
       }

       /*
        * Take care of substitution string
        */
       for ( p = begin = result, subs_len = 0; p[ 0 ] != '\0'; p++ ) {

              /*
               * Keep only single escapes '%'
               */
              if (  !IS_REWRITE_SUBMATCH_ESCAPE( p[ 0 ] ) ) {
                     continue;
              } 

              if (  IS_REWRITE_SUBMATCH_ESCAPE( p[ 1 ] ) ) {
                     /* Pull &p[1] over p, including the trailing '\0' */
                     AC_MEMCPY((char *)p, &p[ 1 ], strlen( p ) );
                     continue;
              }

              tmps = ( struct berval * )realloc( subs,
                            sizeof( struct berval )*( nsub + 1 ) );
              if ( tmps == NULL ) {
                     goto cleanup;
              }
              subs = tmps;
              
              /*
               * I think an `if l > 0' at runtime is better outside than
               * inside a function call ...
               */
              l = p - begin;
              if ( l > 0 ) {
                     subs_len += l;
                     subs[ nsub ].bv_len = l;
                     subs[ nsub ].bv_val = malloc( l + 1 );
                     if ( subs[ nsub ].bv_val == NULL ) {
                            goto cleanup;
                     }
                     AC_MEMCPY( subs[ nsub ].bv_val, begin, l );
                     subs[ nsub ].bv_val[ l ] = '\0';
              } else {
                     subs[ nsub ].bv_val = NULL;
                     subs[ nsub ].bv_len = 0;
              }
              
              /*
               * Substitution pattern
               */
              if ( isdigit( (unsigned char) p[ 1 ] ) ) {
                     struct rewrite_submatch *tmpsm;
                     int d = p[ 1 ] - '0';

                     /*
                      * Add a new value substitution scheme
                      */

                     tmpsm = ( struct rewrite_submatch * )realloc( submatch,
                                   sizeof( struct rewrite_submatch )*( nsub + 1 ) );
                     if ( tmpsm == NULL ) {
                            goto cleanup;
                     }
                     submatch = tmpsm;
                     submatch[ nsub ].ls_submatch = d;

                     /*
                      * If there is no argument, use default
                      * (substitute substring as is)
                      */
                     if ( p[ 2 ] != '{' ) {
                            submatch[ nsub ].ls_type = 
                                   REWRITE_SUBMATCH_ASIS;
                            submatch[ nsub ].ls_map = NULL;
                            begin = ++p + 1;

                     } else {
                            struct rewrite_map *map;

                            submatch[ nsub ].ls_type =
                                   REWRITE_SUBMATCH_XMAP;

                            map = rewrite_xmap_parse( info,
                                          p + 3, (const char **)&begin );
                            if ( map == NULL ) {
                                   goto cleanup;
                            }
                            submatch[ nsub ].ls_map = map;
                            p = begin - 1;
                     }

              /*
               * Map with args ...
               */
              } else if ( p[ 1 ] == '{' ) {
                     struct rewrite_map *map;
                     struct rewrite_submatch *tmpsm;

                     map = rewrite_map_parse( info, p + 2,
                                   (const char **)&begin );
                     if ( map == NULL ) {
                            goto cleanup;
                     }
                     p = begin - 1;

                     /*
                      * Add a new value substitution scheme
                      */
                     tmpsm = ( struct rewrite_submatch * )realloc( submatch,
                                   sizeof( struct rewrite_submatch )*( nsub + 1 ) );
                     if ( tmpsm == NULL ) {
                            goto cleanup;
                     }
                     submatch = tmpsm;
                     submatch[ nsub ].ls_type =
                            REWRITE_SUBMATCH_MAP_W_ARG;
                     submatch[ nsub ].ls_map = map;

              /*
               * Escape '%' ...
               */
              } else if ( p[ 1 ] == '%' ) {
                     AC_MEMCPY( &p[ 1 ], &p[ 2 ], strlen( &p[ 1 ] ) );
                     continue;

              } else {
                     goto cleanup;
              }

              nsub++;
       }
       
       /*
        * Last part of string
        */
       tmps = (struct berval * )realloc( subs, sizeof( struct berval )*( nsub + 1 ) );
       if ( tmps == NULL ) {
              /*
               * XXX need to free the value subst stuff!
               */
              free( subs );
              goto cleanup;
       }
       subs = tmps;
       l = p - begin;
       if ( l > 0 ) {
              subs_len += l;
              subs[ nsub ].bv_len = l;
              subs[ nsub ].bv_val = malloc( l + 1 );
              if ( subs[ nsub ].bv_val == NULL ) {
                     free( subs );
                     goto cleanup;
              }
              AC_MEMCPY( subs[ nsub ].bv_val, begin, l );
              subs[ nsub ].bv_val[ l ] = '\0';
       } else {
              subs[ nsub ].bv_val = NULL;
              subs[ nsub ].bv_len = 0;
       }

       s = calloc( sizeof( struct rewrite_subst ), 1 );
       if ( s == NULL ) {
              goto cleanup;
       }

       s->lt_subs_len = subs_len;
        s->lt_subs = subs;
        s->lt_num_submatch = nsub;
        s->lt_submatch = submatch;

cleanup:;
       free( result );

       return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_subst_destroy ( struct rewrite_subst **  subst)

Definition at line 453 of file subst.c.

{
       int                  n;
       struct rewrite_subst *subst;

       assert( psubst != NULL );
       assert( *psubst != NULL );

       subst = *psubst;

       for ( n = 0; n < subst->lt_num_submatch; n++ ) {
              if ( subst->lt_subs[ n ].bv_val ) {
                     free( subst->lt_subs[ n ].bv_val );
                     subst->lt_subs[ n ].bv_val = NULL;
              }

              switch ( subst->lt_submatch[ n ].ls_type ) {
              case REWRITE_SUBMATCH_ASIS:
                     break;

              case REWRITE_SUBMATCH_XMAP:
                     rewrite_xmap_destroy( &subst->lt_submatch[ n ].ls_map );
                     break;

              case REWRITE_SUBMATCH_MAP_W_ARG:
                     rewrite_map_destroy( &subst->lt_submatch[ n ].ls_map );
                     break;

              default:
                     break;
              }
       }

       free( subst->lt_submatch );
       subst->lt_submatch = NULL;

       /* last one */
       if ( subst->lt_subs[ n ].bv_val ) {
              free( subst->lt_subs[ n ].bv_val );
              subst->lt_subs[ n ].bv_val = NULL;
       }

       free( subst->lt_subs );
       subst->lt_subs = NULL;

       free( subst );
       *psubst = NULL;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_var_delete ( Avlnode *  tree)

Definition at line 93 of file var.c.

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_var_find ( Avlnode *  tree,
const char *  name 
) [read]

Definition at line 105 of file var.c.

{
       struct rewrite_var var;

       assert( name != NULL );

       var.lv_name = ( char * )name;
       return ( struct rewrite_var * )avl_find( tree, 
                     ( caddr_t )&var, rewrite_var_cmp );
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_var_insert_f ( Avlnode **  tree,
const char *  name,
const char *  value,
int  flags 
) [read]

Definition at line 171 of file var.c.

{
       struct rewrite_var *var;
       int rc = 0;

       assert( tree != NULL );
       assert( name != NULL );
       assert( value != NULL );
       
       var = rewrite_var_find( *tree, name );
       if ( var != NULL ) {
              if ( flags & REWRITE_VAR_UPDATE ) {
                     (void)rewrite_var_replace( var, value, flags );
                     goto cleanup;
              }
              rc = -1;
              goto cleanup;
       }

       var = calloc( sizeof( struct rewrite_var ), 1 );
       if ( var == NULL ) {
              return NULL;
       }

       memset( var, 0, sizeof( struct rewrite_var ) );

       if ( flags & REWRITE_VAR_COPY_NAME ) {
              var->lv_name = strdup( name );
              if ( var->lv_name == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              var->lv_flags |= REWRITE_VAR_COPY_NAME;

       } else {
              var->lv_name = (char *)name;
       }

       if ( flags & REWRITE_VAR_COPY_VALUE ) {
              var->lv_value.bv_val = strdup( value );
              if ( var->lv_value.bv_val == NULL ) {
                     rc = -1;
                     goto cleanup;
              }
              var->lv_flags |= REWRITE_VAR_COPY_VALUE;
              
       } else {
              var->lv_value.bv_val = (char *)value;
       }
       var->lv_value.bv_len = strlen( value );
       rc = avl_insert( tree, ( caddr_t )var,
                     rewrite_var_cmp, rewrite_var_dup );

cleanup:;
       if ( rc != 0 && var ) {
              avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
              rewrite_var_free( var );
              var = NULL;
       }

       return var;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_var_replace ( struct rewrite_var var,
const char *  value,
int  flags 
)

Definition at line 120 of file var.c.

{
       ber_len_t     len;

       assert( value != NULL );

       len = strlen( value );

       if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
              if ( flags & REWRITE_VAR_COPY_VALUE ) {
                     if ( len <= var->lv_value.bv_len ) {
                            AC_MEMCPY(var->lv_value.bv_val, value, len + 1);

                     } else {
                            free( var->lv_value.bv_val );
                            var->lv_value.bv_val = strdup( value );
                     }

              } else {
                     free( var->lv_value.bv_val );
                     var->lv_value.bv_val = (char *)value;
                     var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
              }

       } else {
              if ( flags & REWRITE_VAR_COPY_VALUE ) {
                     var->lv_value.bv_val = strdup( value );
                     var->lv_flags |= REWRITE_VAR_COPY_VALUE;

              } else {
                     var->lv_value.bv_val = (char *)value;
              }
       }

       if ( var->lv_value.bv_val == NULL ) {
              return -1;
       }

       var->lv_value.bv_len = len;

       return 0;
}

Here is the caller graph for this function:

rewrite_var_set_f ( Avlnode **  tree,
const char *  name,
const char *  value,
int  flags 
) [read]

Definition at line 243 of file var.c.

{
       struct rewrite_var *var;

       assert( tree != NULL );
       assert( name != NULL );
       assert( value != NULL );
       
       var = rewrite_var_find( *tree, name );
       if ( var == NULL ) {
              if ( flags & REWRITE_VAR_INSERT ) {
                     return rewrite_var_insert_f( tree, name, value, flags );

              } else {
                     return NULL;
              }

       } else {
              assert( var->lv_value.bv_val != NULL );

              (void)rewrite_var_replace( var, value, flags );
       }

       return var;
}

Here is the call graph for this function:

rewrite_xmap_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_map map,
struct berval key,
struct berval val 
)

Definition at line 240 of file xmap.c.

{
       int rc = REWRITE_SUCCESS;
       
       assert( info != NULL );
       assert( op != NULL );
       assert( map != NULL );
       assert( key != NULL );
       assert( val != NULL );
       
       val->bv_val = NULL;
       val->bv_len = 0;
       
       switch ( map->lm_type ) {
#ifdef HAVE_GETPWNAM
       case REWRITE_MAP_XPWDMAP: {
              struct passwd *pwd;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_lock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
              
              pwd = getpwnam( key->bv_val );
              if ( pwd == NULL ) {

#ifdef USE_REWRITE_LDAP_PVT_THREADS
                     ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

                     rc = LDAP_NO_SUCH_OBJECT;
                     break;
              }

#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
              if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) {
                     int l = strlen( pwd->pw_gecos );
                     
                     val->bv_val = strdup( pwd->pw_gecos );
                     val->bv_len = l;
              } else
#endif /* HAVE_STRUCT_PASSWD_PW_GECOS */
              {
                     val->bv_val = strdup( key->bv_val );
                     val->bv_len = key->bv_len;
              }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              if ( val->bv_val == NULL ) {
                     rc = REWRITE_ERR;
              }
              break;
       }
#endif /* HAVE_GETPWNAM*/
       
       case REWRITE_MAP_XFILEMAP: {
              char buf[1024];
              
              if ( map->lm_args == NULL ) {
                     rc = REWRITE_ERR;
                     break;
              }
              
#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_lock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              rewind( ( FILE * )map->lm_args );
              
              while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) {
                     char *p;
                     int blen;
                     
                     blen = strlen( buf );
                     if ( buf[ blen - 1 ] == '\n' ) {
                            buf[ blen - 1 ] = '\0';
                     }
                     
                     p = strtok( buf, " " );
                     if ( p == NULL ) {
#ifdef USE_REWRITE_LDAP_PVT_THREADS
                            ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
                            rc = REWRITE_ERR;
                            goto rc_return;
                     }
                     if ( strcasecmp( p, key->bv_val ) == 0 
                                   && ( p = strtok( NULL, "" ) ) ) {
                            val->bv_val = strdup( p );
                            if ( val->bv_val == NULL ) {
                                   return REWRITE_ERR;
                            }

                            val->bv_len = strlen( p );
                            
#ifdef USE_REWRITE_LDAP_PVT_THREADS
                            ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
                            
                            goto rc_return;
                     }
              }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              rc = REWRITE_ERR;
              
              break;
       }

       case REWRITE_MAP_XLDAPMAP: {
              LDAP *ld;
              char filter[1024];
              LDAPMessage *res = NULL, *entry;
              LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args;
              int attrsonly = 0;
              char **values;

              assert( lud != NULL );

              /*
               * No mutex because there is no write on the map data
               */
              
              ld = ldap_init( lud->lud_host, lud->lud_port );
              if ( ld == NULL ) {
                     rc = REWRITE_ERR;
                     goto rc_return;
              }

              snprintf( filter, sizeof( filter ), lud->lud_filter,
                            key->bv_val );

              if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
                     attrsonly = 1;
              }
              rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope,
                            filter, lud->lud_attrs, attrsonly, &res );
              if ( rc != LDAP_SUCCESS ) {
                     ldap_unbind( ld );
                     rc = REWRITE_ERR;
                     goto rc_return;
              }

              if ( ldap_count_entries( ld, res ) != 1 ) {
                     ldap_unbind( ld );
                     rc = REWRITE_ERR;
                     goto rc_return;
              }

              entry = ldap_first_entry( ld, res );
              if ( entry == NULL ) {
                     ldap_msgfree( res );
                     ldap_unbind( ld );
                     rc = REWRITE_ERR;
                     goto rc_return;
              }
              if ( attrsonly == 1 ) {
                     val->bv_val = ldap_get_dn( ld, entry );

              } else {
                     values = ldap_get_values( ld, entry,
                                   lud->lud_attrs[0] );
                     if ( values != NULL ) {
                            val->bv_val = strdup( values[ 0 ] );
                            ldap_value_free( values );
                     }
              }

              ldap_msgfree( res );
              ldap_unbind( ld );
              
              if ( val->bv_val == NULL ) {
                     rc = REWRITE_ERR;
                     goto rc_return;
              }
              val->bv_len = strlen( val->bv_val );

              rc = REWRITE_SUCCESS;
       } break;
       }

rc_return:;
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_xmap_destroy ( struct rewrite_map **  map)

Definition at line 437 of file xmap.c.

{
       struct rewrite_map *map;

       assert( pmap != NULL );
       assert( *pmap != NULL );

       map = *pmap;

       switch ( map->lm_type ) {
       case REWRITE_MAP_XPWDMAP:
#ifdef USE_REWRITE_LDAP_PVT_THREADS
              --xpasswd_mutex_init;
              if ( !xpasswd_mutex_init ) {
                     ldap_pvt_thread_mutex_destroy( &xpasswd_mutex );
              }
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              break;

       case REWRITE_MAP_XFILEMAP:
#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_lock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              if ( map->lm_args ) {
                     fclose( ( FILE * )map->lm_args );
                     map->lm_args = NULL;
              }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
              ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
              break;

       case REWRITE_MAP_XLDAPMAP:
#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_lock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              if ( map->lm_args ) {
                     ldap_free_urldesc( ( LDAPURLDesc * )map->lm_args );
                     map->lm_args = NULL;
              }

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
              ldap_pvt_thread_mutex_destroy( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
              break;

       default:
              break;

       }

       free( map->lm_name );
       free( map );
       *pmap = NULL;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

rewrite_xmap_parse ( struct rewrite_info info,
const char *  s,
const char **  end 
) [read]

Definition at line 46 of file xmap.c.

{
       struct rewrite_map *map;

       assert( info != NULL );
       assert( s != NULL );
       assert( currpos != NULL );

       Debug( LDAP_DEBUG_ARGS, "rewrite_xmap_parse: %s\n%s%s",
                     s, "", "" );

       *currpos = NULL;

       map = calloc( sizeof( struct rewrite_map ), 1 );
       if ( map == NULL ) {
              Debug( LDAP_DEBUG_ANY, "rewrite_xmap_parse:"
                            " calloc failed\n%s%s%s", "", "", "" );
              return NULL;
       }

       /*
        * Experimental passwd map:
        * replaces the uid with the matching gecos from /etc/passwd file 
        */
       if ( strncasecmp(s, "xpasswd", 7 ) == 0 ) {
              map->lm_type = REWRITE_MAP_XPWDMAP;
              map->lm_name = strdup( "xpasswd" );
              if ( map->lm_name == NULL ) {
                     free( map );
                     return NULL;
              }

              assert( s[7] == '}' );
              *currpos = s + 8;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
              if ( !xpasswd_mutex_init ) {
                     if ( ldap_pvt_thread_mutex_init( &xpasswd_mutex ) ) {
                            free( map );
                            return NULL;
                     }
              }
              ++xpasswd_mutex_init;
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              /* Don't really care if fails */
              return map;
       
       /*
        * Experimental file map:
        * looks up key in a `key value' ascii file
        */
       } else if ( strncasecmp( s, "xfile", 5 ) == 0 ) {
              char *filename;
              const char *p;
              int l;
              int c = 5;
              
              map->lm_type = REWRITE_MAP_XFILEMAP;
              
              if ( s[ c ] != '(' ) {
                     free( map );
                     return NULL;
              }

              /* Must start with '/' for security concerns */
              c++;
              if ( s[ c ] != '/' ) {
                     free( map );
                     return NULL;
              }

              for ( p = s + c; p[ 0 ] != '\0' && p[ 0 ] != ')'; p++ );
              if ( p[ 0 ] != ')' ) {
                     free( map );
                     return NULL;
              }

              l = p - s - c;
              filename = calloc( sizeof( char ), l + 1 );
              if ( filename == NULL ) {
                     free( map );
                     return NULL;
              }
              AC_MEMCPY( filename, s + c, l );
              filename[ l ] = '\0';
              
              map->lm_args = ( void * )fopen( filename, "r" );
              free( filename );

              if ( map->lm_args == NULL ) {
                     free( map );
                     return NULL;
              }

              *currpos = p + 1;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
                if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
                     fclose( ( FILE * )map->lm_args );
                     free( map );
                     return NULL;
              }
#endif /* USE_REWRITE_LDAP_PVT_THREADS */ 
              
              return map;

       /*
         * Experimental ldap map:
         * looks up key on the fly (not implemented!)
         */
        } else if ( strncasecmp(s, "xldap", 5 ) == 0 ) {
              char *p;
              char *url;
              int l, rc;
              int c = 5;
              LDAPURLDesc *lud;

              if ( s[ c ] != '(' ) {
                     free( map );
                     return NULL;
              }
              c++;
              
              p = strchr( s, '}' );
              if ( p == NULL ) {
                     free( map );
                     return NULL;
              }
              p--;

              *currpos = p + 2;
       
              /*
               * Add two bytes for urlencoding of '%s'
               */
              l = p - s - c;
              url = calloc( sizeof( char ), l + 3 );
              if ( url == NULL ) {
                     free( map );
                     return NULL;
              }
              AC_MEMCPY( url, s + c, l );
              url[ l ] = '\0';

              /*
               * Urlencodes the '%s' for ldap_url_parse
               */
              p = strchr( url, '%' );
              if ( p != NULL ) {
                     AC_MEMCPY( p + 3, p + 1, strlen( p + 1 ) + 1 );
                     p[ 1 ] = '2';
                     p[ 2 ] = '5';
              }

              rc =  ldap_url_parse( url, &lud );
              free( url );

              if ( rc != LDAP_SUCCESS ) {
                     free( map );
                     return NULL;
              }
              assert( lud != NULL );

              map->lm_args = ( void * )lud;
              map->lm_type = REWRITE_MAP_XLDAPMAP;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
                if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) {
                     ldap_free_urldesc( lud );
                     free( map );
                     return NULL;
              }
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

              return map;
       
       /* Unhandled map */
       }

       free( map );
       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function: