#include <portable.h>
#include "rewrite-int.h"
#include "rewrite-map.h"
static int
rewrite_parse_builtin_map(
struct rewrite_info *info,
const char *fname,
int lineno,
int argc,
char **argv
);
int
rewrite_parse(
struct rewrite_info *info,
const char *fname,
int lineno,
int argc,
char **argv
)
{
int rc = -1;
assert( info != NULL );
assert( fname != NULL );
assert( argv != NULL );
assert( argc > 0 );
if ( strcasecmp( argv[ 0 ], "rewriteEngine" ) == 0 ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteEngine needs 'state'\n%s",
fname, lineno, "" );
return -1;
} else if ( argc > 2 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] extra fields in rewriteEngine"
" will be discarded\n%s",
fname, lineno, "" );
}
if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) {
info->li_state = REWRITE_ON;
} else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) {
info->li_state = REWRITE_OFF;
} else {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] unknown 'state' in rewriteEngine;"
" assuming 'on'\n%s",
fname, lineno, "" );
info->li_state = REWRITE_ON;
}
rc = REWRITE_SUCCESS;
} else if ( strcasecmp( argv[ 0 ], "rewriteMaxPasses" ) == 0 ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteMaxPasses needs 'value'\n%s",
fname, lineno, "" );
return -1;
}
info->li_max_passes = atoi( argv[ 1 ] );
if ( info->li_max_passes <= 0 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPasses'\n",
fname, lineno, 0 );
}
if ( argc > 2 ) {
info->li_max_passes_per_rule = atoi( argv[ 2 ] );
if ( info->li_max_passes_per_rule <= 0 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPassesPerRule'\n",
fname, lineno, 0 );
}
} else {
info->li_max_passes_per_rule = info->li_max_passes;
}
rc = REWRITE_SUCCESS;
} else if ( strcasecmp( argv[ 0 ], "rewriteContext" ) == 0 ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteContext needs 'name'\n%s",
fname, lineno, "" );
return -1;
}
rewrite_int_curr_context = rewrite_context_find( info, argv[ 1 ] );
if ( rewrite_int_curr_context == NULL ) {
rewrite_int_curr_context = rewrite_context_create( info,
argv[ 1 ] );
}
if ( rewrite_int_curr_context == NULL ) {
return -1;
}
if ( argc > 2 ) {
if ( strcasecmp( argv[ 2 ], "alias" ) == 0 ) {
struct rewrite_context *aliased;
if ( argc == 3 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteContext"
" needs 'name' after"
" 'alias'\n%s",
fname, lineno, "" );
return -1;
} else if ( argc > 4 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] extra fields in"
" rewriteContext"
" after aliased name"
" will be"
" discarded\n%s",
fname, lineno, "" );
}
aliased = rewrite_context_find( info,
argv[ 3 ] );
if ( aliased == NULL ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] aliased"
" rewriteContext '%s'"
" does not exists\n",
fname, lineno,
argv[ 3 ] );
return -1;
}
rewrite_int_curr_context->lc_alias = aliased;
rewrite_int_curr_context = aliased;
} else {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] extra fields"
" in rewriteContext"
" will be discarded\n%s",
fname, lineno, "" );
}
}
rc = REWRITE_SUCCESS;
} else if ( strcasecmp( argv[ 0 ], "rewriteRule" ) == 0 ) {
if ( argc < 3 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteRule needs 'pattern'"
" 'subst' ['flags']\n%s",
fname, lineno, "" );
return -1;
} else if ( argc > 4 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] extra fields in rewriteRule"
" will be discarded\n%s",
fname, lineno, "" );
}
if ( rewrite_int_curr_context == NULL ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteRule outside a"
" context; will add to default\n%s",
fname, lineno, "" );
rewrite_int_curr_context = rewrite_context_find( info,
REWRITE_DEFAULT_CONTEXT );
assert( rewrite_int_curr_context != NULL );
}
rc = rewrite_rule_compile( info, rewrite_int_curr_context, argv[ 1 ],
argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) );
} else if ( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 ) {
if ( argc < 3 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteMap needs at least 'type'"
" and 'name' ['args']\n%s",
fname, lineno, "" );
return -1;
}
rc = rewrite_parse_builtin_map( info, fname, lineno,
argc, argv );
} else if ( strcasecmp( argv[ 0 ], "rewriteParam" ) == 0 ) {
if ( argc < 3 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] rewriteParam needs 'name'"
" and 'value'\n%s",
fname, lineno, "" );
return -1;
}
rc = rewrite_param_set( info, argv[ 1 ], argv[ 2 ] );
} else {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] unknown command '%s'\n",
fname, lineno, "" );
return -1;
}
return rc;
}
static int
rewrite_builtin_map_cmp(
const void *c1,
const void *c2
)
{
const struct rewrite_builtin_map *m1, *m2;
m1 = ( const struct rewrite_builtin_map * )c1;
m2 = ( const struct rewrite_builtin_map * )c2;
assert( m1 != NULL );
assert( m2 != NULL );
assert( m1->lb_name != NULL );
assert( m2->lb_name != NULL );
return strcasecmp( m1->lb_name, m2->lb_name );
}
static int
rewrite_builtin_map_dup(
void *c1,
void *c2
)
{
struct rewrite_builtin_map *m1, *m2;
m1 = ( struct rewrite_builtin_map * )c1;
m2 = ( struct rewrite_builtin_map * )c2;
assert( m1 != NULL );
assert( m2 != NULL );
assert( m1->lb_name != NULL );
assert( m2->lb_name != NULL );
return ( strcasecmp( m1->lb_name, m2->lb_name ) == 0 ? -1 : 0 );
}
static int
rewrite_builtin_map_insert(
struct rewrite_info *info,
struct rewrite_builtin_map *map
)
{
return avl_insert( &info->li_maps, ( caddr_t )map,
rewrite_builtin_map_cmp,
rewrite_builtin_map_dup );
}
struct rewrite_builtin_map *
rewrite_builtin_map_find(
struct rewrite_info *info,
const char *name
)
{
struct rewrite_builtin_map tmp;
assert( info != NULL );
assert( name != NULL );
tmp.lb_name = ( char * )name;
return ( struct rewrite_builtin_map * )avl_find( info->li_maps,
( caddr_t )&tmp, rewrite_builtin_map_cmp );
}
static int
rewrite_parse_builtin_map(
struct rewrite_info *info,
const char *fname,
int lineno,
int argc,
char **argv
)
{
struct rewrite_builtin_map *map;
#define MAP_TYPE 1
#define MAP_NAME 2
assert( info != NULL );
assert( fname != NULL );
assert( argc > 2 );
assert( argv != NULL );
assert( strcasecmp( argv[ 0 ], "rewriteMap" ) == 0 );
map = calloc( sizeof( struct rewrite_builtin_map ), 1 );
if ( map == NULL ) {
return REWRITE_ERR;
}
map->lb_name = strdup( argv[ MAP_NAME ] );
if ( map->lb_name == NULL ) {
free( map );
return REWRITE_ERR;
}
if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
free( map->lb_name );
free( map );
return REWRITE_ERR;
}
#endif
map->lb_private = map_ldap_parse( info, fname, lineno,
argc - 3, argv + 3 );
} else {
Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown map type\n%s",
fname, lineno, "" );
return -1;
}
return rewrite_builtin_map_insert( info, map );
}