Commit 9b10fb82 authored by Ondřej Kuzník's avatar Ondřej Kuzník
Browse files

ITS#9817 Introduce DN and filter manipulation tools

parent 475431aa
Pipeline #4348 passed with stage
in 43 minutes
......@@ -17,11 +17,11 @@
##
SRCS = config.c context.c info.c ldapmap.c map.c params.c rule.c \
session.c subst.c var.c xmap.c \
session.c subst.c var.c xmap.c escapemap.c \
parse.c rewrite.c
XSRCS = version.c
OBJS = config.o context.o info.o ldapmap.o map.o params.o rule.o \
session.o subst.o var.o xmap.o
session.o subst.o var.o xmap.o escapemap.o
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
......
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2000-2022 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENT:
* This work was initially developed by Ondřej Kuzník for inclusion in OpenLDAP
* Software.
*/
#include <portable.h>
#define LDAP_DEPRECATED 1
#include "rewrite-int.h"
#include "rewrite-map.h"
#include <ldap_pvt.h>
typedef int (escape_fn)(
struct berval *input,
struct berval *output );
/*
* Map configuration, a NULL-terminated list of escape_fn pointers
*/
struct escape_map_data {
escape_fn **fn;
};
/*
* (un)escape functions
*/
static int
map_escape_to_filter( struct berval *input, struct berval *output )
{
return ldap_bv2escaped_filter_value( input, output );
}
static int
map_unescape_filter( struct berval *input, struct berval *output )
{
ber_slen_t len;
if ( ber_dupbv( output, input ) == NULL ) {
return REWRITE_ERR;
}
len = ldap_pvt_filter_value_unescape( output->bv_val );
if ( len < 0 ) return REWRITE_ERR;
output->bv_len = len;
return LDAP_SUCCESS;
}
static int
map_escape_to_dn( struct berval *input, struct berval *output )
{
LDAPAVA ava = { .la_attr = BER_BVC("uid"),
.la_value = *input,
.la_flags = LDAP_AVA_STRING },
*ava_[] = { &ava, NULL };
LDAPRDN rdn[] = { ava_, NULL };
LDAPDN dn = rdn;
struct berval dnstr;
char *p;
int rc;
rc = ldap_dn2bv( dn, &dnstr, LDAP_DN_FORMAT_LDAPV3 );
if ( rc != LDAP_SUCCESS ) {
return REWRITE_ERR;
}
p = strchr( dnstr.bv_val, '=' );
p++;
output->bv_len = dnstr.bv_len - ( p - dnstr.bv_val );
output->bv_val = malloc( output->bv_len + 1 );
if ( output->bv_val == NULL ) {
free( dnstr.bv_val );
return REWRITE_ERR;
}
memcpy( output->bv_val, p, output->bv_len );
output->bv_val[output->bv_len] = '\0';
free( dnstr.bv_val );
return REWRITE_SUCCESS;
}
static int
map_unescape_dn( struct berval *input, struct berval *output )
{
LDAPDN dn;
struct berval fake_dn;
char *p;
int rc = REWRITE_SUCCESS;
fake_dn.bv_len = input->bv_len + STRLENOF("uid=");
fake_dn.bv_val = p = malloc( fake_dn.bv_len );
if ( p == NULL ) {
return REWRITE_ERR;
}
memcpy( p, "uid=", STRLENOF("uid=") );
p += STRLENOF("uid=");
memcpy( p, input->bv_val, input->bv_len );
if ( ldap_bv2dn( &fake_dn, &dn, LDAP_DN_FORMAT_LDAPV3 ) != LDAP_SUCCESS ) {
return REWRITE_ERR;
}
if ( ber_dupbv( output, &dn[0][0]->la_value ) == NULL ) {
rc = REWRITE_ERR;
}
ldap_dnfree( dn );
return rc;
}
static void *
map_escape_parse(
const char *fname,
int lineno,
int argc,
char **argv
)
{
escape_fn **fns;
int i;
assert( fname != NULL );
assert( argv != NULL );
if ( argc < 1 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] escape map needs at least one operation\n",
fname, lineno );
return NULL;
}
fns = calloc( sizeof( escape_fn* ), argc + 1 );
if ( fns == NULL ) {
return NULL;
}
for ( i = 0; i < argc; i++ ) {
if ( strcasecmp( argv[i], "escape2dn" ) == 0 ) {
fns[i] = map_escape_to_dn;
} else if ( strcasecmp( argv[i], "escape2filter" ) == 0 ) {
fns[i] = map_escape_to_filter;
} else if ( strcasecmp( argv[i], "unescapedn" ) == 0 ) {
fns[i] = map_unescape_dn;
} else if ( strcasecmp( argv[i], "unescapefilter" ) == 0 ) {
fns[i] = map_unescape_filter;
} else {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] unknown option %s (ignored)\n",
fname, lineno, argv[i] );
free( fns );
return NULL;
}
}
return (void *)fns;
}
static int
map_escape_apply(
void *private,
const char *input,
struct berval *output )
{
escape_fn **fns = private;
struct berval tmpin, tmpout;
int rc, i;
assert( private != NULL );
assert( input != NULL );
assert( output != NULL );
ber_str2bv( input, 0, 1, &tmpin );
for ( i=0; fns[i]; i++ ) {
rc = fns[i]( &tmpin, &tmpout );
free( tmpin.bv_val );
if ( rc != REWRITE_SUCCESS ) {
return rc;
}
tmpin = tmpout;
}
*output = tmpin;
return rc;
}
static int
map_escape_destroy(
void *private
)
{
struct ldap_map_data *data = private;
assert( private != NULL );
free( data );
return 0;
}
const rewrite_mapper rewrite_escape_mapper = {
"escape",
map_escape_parse,
map_escape_apply,
map_escape_destroy
};
......@@ -528,6 +528,9 @@ rewrite_map_destroy(
/* ldapmap.c */
extern const rewrite_mapper rewrite_ldap_mapper;
/* escapemap.c */
extern const rewrite_mapper rewrite_escape_mapper;
const rewrite_mapper *
rewrite_mapper_find(
const char *name
......@@ -538,6 +541,9 @@ rewrite_mapper_find(
if ( !strcasecmp( name, "ldap" ))
return &rewrite_ldap_mapper;
if ( !strcasecmp( name, "escape" ))
return &rewrite_escape_mapper;
for (i=0; i<num_mappers; i++)
if ( !strcasecmp( name, mappers[i]->rm_name ))
return mappers[i];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment