mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 00:29:35 -05:00
ITS#10104 Add slapo-alias to contrib
This commit is contained in:
parent
2c73d3a534
commit
d615deb6f6
33 changed files with 1753 additions and 0 deletions
|
|
@ -9,3 +9,4 @@ OLcfgCt{Oc|At}:6 adremap
|
|||
OLcfgCt{Oc|At}:7 rbac
|
||||
OLcfgCt{Oc|At}:8 datamorph
|
||||
OLcfgCt{Oc|At}:9 variant
|
||||
OLcfgCt{Oc|At}:10 alias
|
||||
|
|
|
|||
3
contrib/slapd-modules/alias/.gitignore
vendored
Normal file
3
contrib/slapd-modules/alias/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# test suite
|
||||
clients
|
||||
servers
|
||||
82
contrib/slapd-modules/alias/Makefile
Normal file
82
contrib/slapd-modules/alias/Makefile
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# $OpenLDAP$
|
||||
# This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
#
|
||||
# Copyright 1998-2023 The OpenLDAP Foundation.
|
||||
# Copyright 2023 Ondřej Kuzník, Symas Corp. 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>.
|
||||
|
||||
LDAP_SRC = ../../..
|
||||
LDAP_BUILD = $(LDAP_SRC)
|
||||
SRCDIR = ./
|
||||
LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
|
||||
LDAP_LIB = $(LDAP_BUILD)/libraries/libldap/libldap.la \
|
||||
$(LDAP_BUILD)/libraries/liblber/liblber.la
|
||||
|
||||
PLAT = UNIX
|
||||
NT_LIB = -L$(LDAP_BUILD)/servers/slapd -lslapd
|
||||
NT_LDFLAGS = -no-undefined -avoid-version
|
||||
UNIX_LDFLAGS = -version-info $(LTVER)
|
||||
|
||||
LIBTOOL = $(LDAP_BUILD)/libtool
|
||||
INSTALL = /usr/bin/install
|
||||
CC = gcc
|
||||
OPT = -g -O2
|
||||
DEFS = -DSLAPD_OVER_ALIAS=SLAPD_MOD_DYNAMIC
|
||||
INCS = $(LDAP_INC)
|
||||
LIBS = $($(PLAT)_LIB) $(LDAP_LIB)
|
||||
LD_FLAGS = $(LDFLAGS) $($(PLAT)_LDFLAGS) -rpath $(moduledir) -module
|
||||
|
||||
PROGRAMS = alias.la
|
||||
MANPAGES = slapo-alias.5
|
||||
CLEAN = *.o *.lo *.la .libs
|
||||
LTVER = 0:0:0
|
||||
|
||||
prefix=/usr/local
|
||||
exec_prefix=$(prefix)
|
||||
ldap_subdir=/openldap
|
||||
|
||||
libdir=$(exec_prefix)/lib
|
||||
libexecdir=$(exec_prefix)/libexec
|
||||
moduledir = $(libexecdir)$(ldap_subdir)
|
||||
mandir = $(exec_prefix)/share/man
|
||||
man5dir = $(mandir)/man5
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
d :=
|
||||
sp :=
|
||||
dir := tests
|
||||
include $(dir)/Rules.mk
|
||||
|
||||
.SUFFIXES: .c .o .lo
|
||||
|
||||
.c.lo:
|
||||
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(OPT) $(CPPFLAGS) $(DEFS) $(INCS) -c $<
|
||||
|
||||
alias.la: alias.lo
|
||||
$(LIBTOOL) --mode=link $(CC) $(LD_FLAGS) -o $@ $? $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -rf $(CLEAN)
|
||||
|
||||
install: install-lib install-man FORCE
|
||||
|
||||
install-lib: $(PROGRAMS)
|
||||
mkdir -p $(DESTDIR)$(moduledir)
|
||||
for p in $(PROGRAMS) ; do \
|
||||
$(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
|
||||
done
|
||||
|
||||
install-man: $(MANPAGES)
|
||||
mkdir -p $(DESTDIR)$(man5dir)
|
||||
$(INSTALL) -m 644 $(MANPAGES) $(DESTDIR)$(man5dir)
|
||||
|
||||
FORCE:
|
||||
|
||||
671
contrib/slapd-modules/alias/alias.c
Normal file
671
contrib/slapd-modules/alias/alias.c
Normal file
|
|
@ -0,0 +1,671 @@
|
|||
/* alias.c - expose an attribute under a different name */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2016-2023 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>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
* This work was developed in 2023 by Ondřej Kuzník for Symas Corp.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#ifdef SLAPD_OVER_ALIAS
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ac/stdlib.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "slap-config.h"
|
||||
#include "lutil.h"
|
||||
#include "ldap_queue.h"
|
||||
|
||||
typedef struct alias_mapping_t {
|
||||
AttributeDescription *source;
|
||||
AttributeDescription *alias;
|
||||
} alias_mapping;
|
||||
|
||||
typedef struct alias_info_t {
|
||||
alias_mapping *mappings;
|
||||
} alias_info;
|
||||
|
||||
typedef struct alias_sc_private_t {
|
||||
slap_overinst *on;
|
||||
AttributeName *attrs_orig, *attrs_new;
|
||||
} alias_sc_private;
|
||||
|
||||
static alias_mapping *
|
||||
attribute_mapped( alias_info *ov, AttributeDescription *ad )
|
||||
{
|
||||
alias_mapping *m;
|
||||
|
||||
for ( m = ov->mappings; m && m->source; m++ ) {
|
||||
if ( ad == m->alias ) return m;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_op_add( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
Entry *e = op->ora_e;
|
||||
Attribute *a;
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
if ( !BER_BVISEMPTY( &e->e_nname ) ) {
|
||||
LDAPRDN rDN;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
rc = ldap_bv2rdn_x( &e->e_nname, &rDN, (char **)&p, LDAP_DN_FORMAT_LDAP,
|
||||
op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_ANY, "alias_op_add: "
|
||||
"can't parse rdn: dn=%s\n",
|
||||
op->o_req_ndn.bv_val );
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
for ( i = 0; rDN[i]; i++ ) {
|
||||
AttributeDescription *ad = NULL;
|
||||
|
||||
/* If we can't resolve the attribute, ignore it */
|
||||
if ( slap_bv2ad( &rDN[i]->la_attr, &ad, &p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( attribute_mapped( ov, ad ) ) {
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_rdnfree_x( rDN, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_error( op, rs, rc,
|
||||
"trying to add a virtual attribute in RDN" );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
for ( a = e->e_attrs; a; a = a->a_next ) {
|
||||
if ( attribute_mapped( ov, a->a_desc ) ) {
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
send_ldap_error( op, rs, rc,
|
||||
"trying to add a virtual attribute" );
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_op_compare( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
alias_mapping *alias = attribute_mapped( ov, op->orc_ava->aa_desc );
|
||||
|
||||
if ( alias )
|
||||
op->orc_ava->aa_desc = alias->source;
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_op_mod( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
Modifications *mod;
|
||||
int rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
|
||||
for ( mod = op->orm_modlist; mod; mod = mod->sml_next ) {
|
||||
if ( attribute_mapped( ov, mod->sml_desc ) ) {
|
||||
send_ldap_error( op, rs, rc,
|
||||
"trying to modify a virtual attribute" );
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_op_modrdn( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
LDAPRDN rDN;
|
||||
const char *p;
|
||||
int i, rc = SLAP_CB_CONTINUE;
|
||||
|
||||
rc = ldap_bv2rdn_x( &op->orr_nnewrdn, &rDN, (char **)&p,
|
||||
LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_ANY, "alias_op_modrdn: "
|
||||
"can't parse rdn for dn=%s\n",
|
||||
op->o_req_ndn.bv_val );
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
for ( i = 0; rDN[i]; i++ ) {
|
||||
AttributeDescription *ad = NULL;
|
||||
|
||||
/* If we can't resolve the attribute, ignore it */
|
||||
if ( slap_bv2ad( &rDN[i]->la_attr, &ad, &p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( attribute_mapped( ov, ad ) ) {
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_rdnfree_x( rDN, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_error( op, rs, rc,
|
||||
"trying to add a virtual attribute in RDN" );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_response_cleanup( Operation *op, SlapReply *rs )
|
||||
{
|
||||
alias_sc_private *data = op->o_callback->sc_private;
|
||||
|
||||
if ( rs->sr_type == REP_RESULT || op->o_abandon ||
|
||||
rs->sr_err == SLAPD_ABANDON )
|
||||
{
|
||||
if ( op->ors_attrs == data->attrs_new )
|
||||
op->ors_attrs = data->attrs_orig;
|
||||
|
||||
ch_free( data->attrs_new );
|
||||
ch_free( op->o_callback );
|
||||
op->o_callback = NULL;
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_response( Operation *op, SlapReply *rs )
|
||||
{
|
||||
alias_sc_private *data = op->o_callback->sc_private;
|
||||
slap_overinst *on = data->on;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
Entry *e = NULL, *e_orig = rs->sr_entry;
|
||||
alias_mapping *mapping;
|
||||
int rc = SLAP_CB_CONTINUE;
|
||||
|
||||
if ( rs->sr_type != REP_SEARCH || !e_orig ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
for ( mapping = ov->mappings; mapping && mapping->source; mapping++ ) {
|
||||
Attribute *source, *a;
|
||||
int operational = is_at_operational( mapping->source->ad_type ),
|
||||
keep_source = 0;
|
||||
slap_mask_t requested = operational ?
|
||||
SLAP_OPATTRS_YES : SLAP_USERATTRS_YES;
|
||||
|
||||
if ( !(requested & rs->sr_attr_flags) &&
|
||||
!ad_inlist( mapping->alias, rs->sr_attrs ) )
|
||||
continue;
|
||||
|
||||
/* TODO: deal with multiple aliases from the same source */
|
||||
if ( (requested & rs->sr_attr_flags) ||
|
||||
ad_inlist( mapping->source, data->attrs_orig ) ) {
|
||||
keep_source = 1;
|
||||
}
|
||||
|
||||
if ( operational ) {
|
||||
source = attr_find( rs->sr_operational_attrs, mapping->source );
|
||||
} else {
|
||||
source = attr_find( e_orig->e_attrs, mapping->source );
|
||||
}
|
||||
if ( !source )
|
||||
continue;
|
||||
|
||||
if ( operational ) {
|
||||
if ( !keep_source ) {
|
||||
source->a_desc = mapping->alias;
|
||||
} else {
|
||||
Attribute **ap;
|
||||
|
||||
a = attr_dup( source );
|
||||
a->a_desc = mapping->alias;
|
||||
|
||||
for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next );
|
||||
*ap = a;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !e ) {
|
||||
if ( rs->sr_flags & REP_ENTRY_MODIFIABLE ) {
|
||||
e = e_orig;
|
||||
} else {
|
||||
e = entry_dup( e_orig );
|
||||
}
|
||||
}
|
||||
|
||||
a = attr_find( e->e_attrs, mapping->source );
|
||||
if ( !keep_source ) {
|
||||
a->a_desc = mapping->alias;
|
||||
} else {
|
||||
attr_merge( e, mapping->alias, a->a_vals, a->a_nvals );
|
||||
}
|
||||
}
|
||||
|
||||
if ( e && e != e_orig ) {
|
||||
rs_replace_entry( op, rs, on, e );
|
||||
rs->sr_flags &= ~REP_ENTRY_MASK;
|
||||
rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_filter( alias_info *ov, Filter *f )
|
||||
{
|
||||
int changed = 0;
|
||||
|
||||
switch ( f->f_choice ) {
|
||||
case LDAP_FILTER_AND:
|
||||
case LDAP_FILTER_OR: {
|
||||
for ( f = f->f_and; f; f = f->f_next ) {
|
||||
int result = alias_filter( ov, f );
|
||||
if ( result < 0 ) {
|
||||
return result;
|
||||
}
|
||||
changed += result;
|
||||
}
|
||||
} break;
|
||||
|
||||
case LDAP_FILTER_NOT:
|
||||
return alias_filter( ov, f->f_not );
|
||||
|
||||
case LDAP_FILTER_PRESENT: {
|
||||
alias_mapping *alias = attribute_mapped( ov, f->f_desc );
|
||||
if ( alias ) {
|
||||
f->f_desc = alias->source;
|
||||
changed = 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case LDAP_FILTER_APPROX:
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
case LDAP_FILTER_GE:
|
||||
case LDAP_FILTER_LE: {
|
||||
alias_mapping *alias = attribute_mapped( ov, f->f_av_desc );
|
||||
if ( alias ) {
|
||||
f->f_av_desc = alias->source;
|
||||
changed = 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case LDAP_FILTER_SUBSTRINGS: {
|
||||
alias_mapping *alias = attribute_mapped( ov, f->f_sub_desc );
|
||||
if ( alias ) {
|
||||
f->f_sub_desc = alias->source;
|
||||
changed = 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case LDAP_FILTER_EXT: {
|
||||
alias_mapping *alias = attribute_mapped( ov, f->f_mr_desc );
|
||||
if ( alias ) {
|
||||
f->f_mr_desc = alias->source;
|
||||
changed = 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_op_search( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
alias_mapping *mapping;
|
||||
AttributeName *an_orig = NULL, *an_new = NULL;
|
||||
int mapped, an_length = 0;
|
||||
|
||||
if ( get_manageDSAit( op ) )
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
||||
/*
|
||||
* 1. check filter: traverse, map aliased attributes
|
||||
* 2. unparse filter
|
||||
* 3. check all requested attributes -> register callback if one matches
|
||||
*/
|
||||
if ( (mapped = alias_filter( ov, op->ors_filter )) < 0 ) {
|
||||
send_ldap_error( op, rs, LDAP_OTHER,
|
||||
"alias_op_search: failed to process filter" );
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
if ( mapped ) {
|
||||
op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
|
||||
}
|
||||
|
||||
mapped = 0;
|
||||
for ( mapping = ov->mappings; mapping && mapping->source; mapping++ ) {
|
||||
int operational = is_at_operational( mapping->source->ad_type );
|
||||
slap_mask_t requested = operational ?
|
||||
SLAP_OPATTRS_YES : SLAP_USERATTRS_YES;
|
||||
|
||||
if ( requested & slap_attr_flags( op->ors_attrs ) ) {
|
||||
mapped = 1;
|
||||
} else if ( ad_inlist( mapping->alias, op->ors_attrs ) ) {
|
||||
mapped = 1;
|
||||
if ( !an_length ) {
|
||||
for ( ; !BER_BVISNULL( &op->ors_attrs[an_length].an_name ); an_length++ )
|
||||
/* Count */;
|
||||
}
|
||||
|
||||
an_new = ch_realloc( an_new, (an_length+2)*sizeof(AttributeName) );
|
||||
if ( !an_orig ) {
|
||||
int i;
|
||||
an_orig = op->ors_attrs;
|
||||
for ( i=0; i < an_length; i++ ) {
|
||||
an_new[i] = an_orig[i];
|
||||
}
|
||||
}
|
||||
|
||||
an_new[an_length].an_name = mapping->source->ad_cname;
|
||||
an_new[an_length].an_desc = mapping->source;
|
||||
an_length++;
|
||||
|
||||
BER_BVZERO( &an_new[an_length].an_name );
|
||||
}
|
||||
}
|
||||
|
||||
if ( mapped ) {
|
||||
/* We have something to map back */
|
||||
slap_callback *cb = op->o_tmpcalloc( 1,
|
||||
sizeof(slap_callback)+sizeof(alias_sc_private),
|
||||
op->o_tmpmemctx );
|
||||
alias_sc_private *data = (alias_sc_private *)(cb+1);
|
||||
|
||||
data->on = on;
|
||||
|
||||
cb->sc_response = alias_response;
|
||||
cb->sc_private = data;
|
||||
cb->sc_next = op->o_callback;
|
||||
cb->sc_cleanup = alias_response_cleanup;
|
||||
|
||||
if ( an_new ) {
|
||||
data->attrs_orig = an_orig;
|
||||
data->attrs_new = an_new;
|
||||
op->ors_attrs = an_new;
|
||||
}
|
||||
|
||||
op->o_callback = cb;
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
/* Configuration */
|
||||
|
||||
static ConfigDriver alias_config_mapping;
|
||||
|
||||
static ConfigTable alias_cfg[] = {
|
||||
{ "alias_attribute", "attr> <attr", 3, 3, 0,
|
||||
ARG_MAGIC,
|
||||
alias_config_mapping,
|
||||
"( OLcfgCtAt:10.1 NAME 'olcAliasMapping' "
|
||||
"DESC 'Alias definition' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )",
|
||||
NULL, NULL
|
||||
},
|
||||
|
||||
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: There is no reason to keep olcAliasMapping MAY (making this overlay
|
||||
* a noop) except we can't enforce a MUST with slaptest+slapd.conf.
|
||||
*/
|
||||
static ConfigOCs alias_ocs[] = {
|
||||
{ "( OLcfgCtOc:10.1 "
|
||||
"NAME 'olcAliasConfig' "
|
||||
"DESC 'Alias overlay configuration' "
|
||||
"MAY ( olcAliasMapping ) "
|
||||
"SUP olcOverlayConfig )",
|
||||
Cft_Overlay, alias_cfg },
|
||||
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
alias_config_mapping( ConfigArgs *ca )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)ca->bi;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
AttributeDescription *source = NULL, *alias = NULL;
|
||||
AttributeType *sat, *aat;
|
||||
const char *text;
|
||||
int i, rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
|
||||
if ( ca->op == SLAP_CONFIG_EMIT ) {
|
||||
alias_mapping *mapping;
|
||||
|
||||
for ( mapping = ov->mappings; mapping && mapping->source; mapping++ ) {
|
||||
char buf[SLAP_TEXT_BUFLEN];
|
||||
struct berval bv = { .bv_val = buf, .bv_len = SLAP_TEXT_BUFLEN };
|
||||
bv.bv_len = snprintf( buf, bv.bv_len, "%s %s",
|
||||
mapping->source->ad_cname.bv_val,
|
||||
mapping->alias->ad_cname.bv_val );
|
||||
value_add_one( &ca->rvalue_vals, &bv );
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
} else if ( ca->op == LDAP_MOD_DELETE ) {
|
||||
if ( ca->valx < 0 ) {
|
||||
ch_free( ov->mappings );
|
||||
ov->mappings = NULL;
|
||||
} else {
|
||||
i = ca->valx;
|
||||
do {
|
||||
ov->mappings[i] = ov->mappings[i+1];
|
||||
i++;
|
||||
} while ( ov->mappings[i].source );
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
rc = slap_str2ad( ca->argv[1], &source, &text );
|
||||
if ( rc ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"cannot resolve attribute '%s': \"%s\"",
|
||||
ca->argv[1], text );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = slap_str2ad( ca->argv[2], &alias, &text );
|
||||
if ( rc ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"cannot resolve attribute '%s': \"%s\"",
|
||||
ca->argv[2], text );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
goto done;
|
||||
}
|
||||
|
||||
sat = source->ad_type;
|
||||
aat = alias->ad_type;
|
||||
if ( sat == aat ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"cannot map attribute %s to itself",
|
||||
source->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* The types have to match */
|
||||
if ( is_at_operational( sat ) != is_at_operational( aat ) ||
|
||||
is_at_single_value( sat ) != is_at_single_value( aat ) ||
|
||||
sat->sat_syntax != aat->sat_syntax ||
|
||||
sat->sat_equality != aat->sat_equality ||
|
||||
sat->sat_approx != aat->sat_approx ||
|
||||
sat->sat_ordering != aat->sat_ordering ||
|
||||
sat->sat_substr != aat->sat_substr ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"attributes %s and %s syntax and/or "
|
||||
"default matching rules don't match",
|
||||
source->ad_cname.bv_val,
|
||||
alias->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( !ov->mappings ) {
|
||||
ov->mappings = ch_calloc( 2, sizeof(alias_mapping) );
|
||||
ov->mappings[0].source = source;
|
||||
ov->mappings[0].alias = alias;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for ( i = 0; ov->mappings[i].source; i++ ) {
|
||||
if ( alias == ov->mappings[i].alias ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"attribute %s already mapped from %s",
|
||||
alias->ad_cname.bv_val,
|
||||
ov->mappings[i].source->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
}
|
||||
if ( alias == ov->mappings[i].source ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"cannot use %s as alias source, already mapped from %s",
|
||||
source->ad_cname.bv_val,
|
||||
ov->mappings[i].source->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
}
|
||||
if ( source == ov->mappings[i].alias ) {
|
||||
snprintf( ca->cr_msg, sizeof(ca->cr_msg),
|
||||
"cannot use %s as alias, it is aliased to %s",
|
||||
alias->ad_cname.bv_val,
|
||||
ov->mappings[i].alias->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s\n", ca->log, ca->cr_msg );
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ca->valx < 0 || ca->valx > i )
|
||||
ca->valx = i;
|
||||
|
||||
i++;
|
||||
ov->mappings = ch_realloc( ov->mappings, (i + 1) * sizeof(alias_mapping) );
|
||||
do {
|
||||
ov->mappings[i] = ov->mappings[i-1];
|
||||
} while ( --i > ca->valx );
|
||||
ov->mappings[i].source = source;
|
||||
ov->mappings[i].alias = alias;
|
||||
}
|
||||
|
||||
rc = LDAP_SUCCESS;
|
||||
done:
|
||||
ca->reply.err = rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static slap_overinst alias;
|
||||
|
||||
static int
|
||||
alias_db_init( BackendDB *be, ConfigReply *cr )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
alias_info *ov;
|
||||
|
||||
/* TODO: can this be global? */
|
||||
if ( SLAP_ISGLOBALOVERLAY(be) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "alias overlay must be instantiated "
|
||||
"within a database.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
ov = ch_calloc( 1, sizeof(alias_info) );
|
||||
on->on_bi.bi_private = ov;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_db_destroy( BackendDB *be, ConfigReply *cr )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
alias_info *ov = on->on_bi.bi_private;
|
||||
|
||||
if ( ov && ov->mappings ) {
|
||||
ch_free( ov->mappings );
|
||||
}
|
||||
ch_free( ov );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
alias_initialize()
|
||||
{
|
||||
int rc;
|
||||
|
||||
alias.on_bi.bi_type = "alias";
|
||||
alias.on_bi.bi_db_init = alias_db_init;
|
||||
alias.on_bi.bi_db_destroy = alias_db_destroy;
|
||||
|
||||
alias.on_bi.bi_op_add = alias_op_add;
|
||||
alias.on_bi.bi_op_compare = alias_op_compare;
|
||||
alias.on_bi.bi_op_modify = alias_op_mod;
|
||||
alias.on_bi.bi_op_modrdn = alias_op_modrdn;
|
||||
alias.on_bi.bi_op_search = alias_op_search;
|
||||
|
||||
alias.on_bi.bi_cf_ocs = alias_ocs;
|
||||
|
||||
rc = config_register_schema( alias_cfg, alias_ocs );
|
||||
if ( rc ) return rc;
|
||||
|
||||
return overlay_register( &alias );
|
||||
}
|
||||
|
||||
#if SLAPD_OVER_ALIAS == SLAPD_MOD_DYNAMIC
|
||||
int
|
||||
init_module( int argc, char *argv[] )
|
||||
{
|
||||
return alias_initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SLAPD_OVER_ALIAS */
|
||||
121
contrib/slapd-modules/alias/slapo-alias.5
Normal file
121
contrib/slapd-modules/alias/slapo-alias.5
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
.TH SLAPO-ALIAS 5 "RELEASEDATE" "OpenLDAP"
|
||||
.\" Copyright 2023 Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See LICENSE.
|
||||
.SH NAME
|
||||
slapo\-alias \- expose an attribute under a different name
|
||||
.SH SYNOPSIS
|
||||
olcOverlay=alias
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B alias
|
||||
overlay to
|
||||
.BR slapd (8)
|
||||
allows migrations for existing attributes exposed through a name that is
|
||||
now deprecated where using
|
||||
.BR slapo-rwm (5)
|
||||
is not applicable. For this reason, the aliased attributes are not writable
|
||||
in any way. In particular:
|
||||
|
||||
.RS
|
||||
.TP
|
||||
.B Search
|
||||
|
||||
Instances of the aliased attribute in the
|
||||
.B Search
|
||||
request filter are replaced by the source attribute.
|
||||
|
||||
If the attribute is requested, the values are copied from the source
|
||||
attribute, however unlike with
|
||||
.BR slapo-rwm (5),
|
||||
if the source attribute is also requested, both will be returned.
|
||||
.TP
|
||||
.B Compare
|
||||
The request is mapped to the source attribute before processing.
|
||||
.TP
|
||||
.B Add, Modify, ModRDN
|
||||
Requests affecting aliased attributes are rejected with a
|
||||
.B Constraint
|
||||
.BR Violation .
|
||||
.RE
|
||||
|
||||
|
||||
.SH CONFIGURATION LAYOUT
|
||||
|
||||
The overlay has to be instantiated under a database adding an entry of
|
||||
.B olcOverlay=alias
|
||||
with objectClass of
|
||||
.BR olcAliasConfig.
|
||||
|
||||
These are the available options:
|
||||
|
||||
.RS
|
||||
.TP
|
||||
.B olcAliasMapping: <source-attribute> <aliased-attribute>
|
||||
Any time
|
||||
.B aliased-attribute
|
||||
is requested (explicitly or through
|
||||
.B * +
|
||||
shorthands), the values of
|
||||
.B source-attribute
|
||||
are returned. The attributes need to be compatible i.e. both have to be
|
||||
operational or neither should, same with the
|
||||
.B SINGLE-VALUE
|
||||
option, syntax or matching rules. The
|
||||
.BR slapd.conf (5)
|
||||
equivalent is
|
||||
.BR alias_attribute .
|
||||
It can be provided multiple times.
|
||||
.RE
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
The following is an example of a configured overlay, substitute
|
||||
.B $DATABASE
|
||||
for the DN of the database it is attached to and
|
||||
.B {x}
|
||||
with the desired position of the overlay in the overlay stack.
|
||||
|
||||
.nf
|
||||
dn: olcOverlay={x}alias,$DATABASE
|
||||
objectClass: olcAliasConfig
|
||||
olcOverlay: alias
|
||||
olcAliasMapping: source-attribute aliased-attribute
|
||||
.fi
|
||||
|
||||
The
|
||||
.BR slapd.conf (5)
|
||||
equivalent of the above follows:
|
||||
|
||||
.nf
|
||||
overlay alias
|
||||
|
||||
alias_attribute source-attribute aliased-attribute
|
||||
.fi
|
||||
|
||||
.SH NOTES
|
||||
When mapping an operational attribute, you might need to use
|
||||
.BR slapo-dsaschema (5)
|
||||
contrib module to provide its definition into the schema.
|
||||
|
||||
.SH BUGS AND LIMITATIONS
|
||||
Setting ACLs that differ between the aliased and its source attribute is not
|
||||
supported, they have to match or risk information disclosure.
|
||||
|
||||
It is also expected that the aliased attributes are never physically present in
|
||||
the database.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
ETCDIR/slapd.conf
|
||||
default slapd configuration file
|
||||
.TP
|
||||
ETCDIR/slapd.d
|
||||
default slapd configuration directory
|
||||
.SH SEE ALSO
|
||||
.BR slapd-config (5),
|
||||
.BR slapd.conf (5),
|
||||
.BR slapd.overlays (5),
|
||||
.BR slapo-dsaschema (5),
|
||||
.BR slapd (8)
|
||||
.SH ACKNOWLEDGEMENTS
|
||||
This module was developed in 2023 by Ondřej Kuzník for Symas Corp.
|
||||
4
contrib/slapd-modules/alias/tests/.gitignore
vendored
Normal file
4
contrib/slapd-modules/alias/tests/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
progs
|
||||
schema
|
||||
testdata
|
||||
testrun
|
||||
23
contrib/slapd-modules/alias/tests/Rules.mk
Normal file
23
contrib/slapd-modules/alias/tests/Rules.mk
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
sp := $(sp).x
|
||||
dirstack_$(sp) := $(d)
|
||||
d := $(dir)
|
||||
|
||||
.PHONY: test
|
||||
|
||||
CLEAN += clients servers tests/progs tests/schema tests/testdata tests/testrun
|
||||
|
||||
test: all clients servers tests/progs
|
||||
|
||||
test:
|
||||
cd tests; \
|
||||
SRCDIR=$(abspath $(LDAP_SRC)) \
|
||||
LDAP_BUILD=$(abspath $(LDAP_BUILD)) \
|
||||
TOPDIR=$(abspath $(SRCDIR)) \
|
||||
LIBTOOL=$(abspath $(LIBTOOL)) \
|
||||
$(abspath $(SRCDIR))/tests/run all
|
||||
|
||||
servers clients tests/progs:
|
||||
ln -s $(abspath $(LDAP_BUILD))/$@ $@
|
||||
|
||||
d := $(dirstack_$(sp))
|
||||
sp := $(basename $(sp))
|
||||
4
contrib/slapd-modules/alias/tests/data/alias.conf
Normal file
4
contrib/slapd-modules/alias/tests/data/alias.conf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
overlay alias
|
||||
|
||||
alias_attribute pager mobile
|
||||
|
||||
5
contrib/slapd-modules/alias/tests/data/config.ldif
Normal file
5
contrib/slapd-modules/alias/tests/data/config.ldif
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: add
|
||||
objectClass: olcOverlayConfig
|
||||
objectclass: olcAliasConfig
|
||||
olcAliasMapping: pager mobile
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: description invalidAttr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: invalidAttr description
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: fax mobile
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: c countryname
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: mobile fax
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: fax pager
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: seeAlso entryDN
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: displayName employeeType
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: dc description
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: memberUid mail
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: gidNumber ipServicePort
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
dn: mobile=\+1 313 555 4474,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Just a phone
|
||||
sn: Mobile
|
||||
18
contrib/slapd-modules/alias/tests/data/test002-add.ldif
Normal file
18
contrib/slapd-modules/alias/tests/data/test002-add.ldif
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
dn: cn=Gern Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||
changetype: add
|
||||
objectclass: testPerson
|
||||
cn: Gern Jensen
|
||||
sn: Jensen
|
||||
uid: gjensen
|
||||
title: Chief Investigator, ITD
|
||||
postaladdress: ITD $ 535 W. William St $ Anytown, MI 48103
|
||||
seealso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
drink: Coffee
|
||||
homepostaladdress: 844 Brown St. Apt. 4 $ Anytown, MI 48104
|
||||
description: Very odd
|
||||
facsimiletelephonenumber: +1 313 555 7557
|
||||
telephonenumber: +1 313 555 8343
|
||||
mail: gjensen@mailgw.example.com
|
||||
homephone: +1 313 555 8844
|
||||
testTime: 20050304001801.234Z
|
||||
mobile: +1 313 555 8866
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
delete: mobile
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
add: mobile
|
||||
mobile: +1 313 555 3665
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
|
||||
,dc=com
|
||||
changetype: modrdn
|
||||
newrdn: mobile=\+1 313 555 4474
|
||||
deleteoldrdn: 0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
dn: olcOverlay={0}alias,olcDatabase={1}@BACKEND@,cn=config
|
||||
changetype: modify
|
||||
add: olcAliasMapping
|
||||
olcAliasMapping: title employeeType
|
||||
66
contrib/slapd-modules/alias/tests/data/test003-out.ldif
Normal file
66
contrib/slapd-modules/alias/tests/data/test003-out.ldif
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Listing aliased attribute...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
mobile: +1 313 555 3233
|
||||
|
||||
|
||||
# A search when aliased attribute is not requested...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
pager: +1 313 555 3233
|
||||
|
||||
|
||||
# A search when both are requested (explicitly)...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
pager: +1 313 555 3233
|
||||
mobile: +1 313 555 3233
|
||||
|
||||
|
||||
# A search when both are requested (implicitly)...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Barbara Jensen
|
||||
cn: Babs Jensen
|
||||
sn:: IEplbnNlbiA=
|
||||
uid: bjensen
|
||||
title: Mythical Manager, Research Systems
|
||||
postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
|
||||
own, MI 48103-4943
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
userPassword:: YmplbnNlbg==
|
||||
mail: bjensen@mailgw.example.com
|
||||
homePostalAddress: 123 Wesley $ Anytown, MI 48103
|
||||
description: Mythical manager of the rsdd unix project
|
||||
drink: water
|
||||
homePhone: +1 313 555 2333
|
||||
pager: +1 313 555 3233
|
||||
facsimileTelephoneNumber: +1 313 555 2274
|
||||
telephoneNumber: +1 313 555 9022
|
||||
mobile: +1 313 555 3233
|
||||
|
||||
|
||||
# Testing searches filtering on aliased attributes...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
mobile: +1 313 555 3233
|
||||
|
||||
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
mobile: +1 313 555 4474
|
||||
|
||||
dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
mobile: +1 313 555 1220
|
||||
|
||||
|
||||
# Testing search with new attributes...
|
||||
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
employeeType: Director, Embedded Systems
|
||||
mobile: +1 313 555 4474
|
||||
|
||||
dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
employeeType: Director, UM Alumni Association
|
||||
mobile: +1 313 555 7671
|
||||
|
||||
17
contrib/slapd-modules/alias/tests/run
Executable file
17
contrib/slapd-modules/alias/tests/run
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
## $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 1998-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>.
|
||||
|
||||
TOPSRCDIR="$SRCDIR" OBJDIR="${LDAP_BUILD}" SRCDIR="${SRCDIR}/tests" DEFSDIR="${SRCDIR}/scripts" SCRIPTDIR="${TOPDIR}/tests/scripts" "${LDAP_BUILD}/tests/run" $*
|
||||
|
||||
93
contrib/slapd-modules/alias/tests/scripts/all
Executable file
93
contrib/slapd-modules/alias/tests/scripts/all
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
#! /bin/sh
|
||||
# $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 1998-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>.
|
||||
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
TB="" TN=""
|
||||
if test -t 1 ; then
|
||||
TB=`$SHTOOL echo -e "%B" 2>/dev/null`
|
||||
TN=`$SHTOOL echo -e "%b" 2>/dev/null`
|
||||
fi
|
||||
|
||||
FAILCOUNT=0
|
||||
SKIPCOUNT=0
|
||||
SLEEPTIME=10
|
||||
|
||||
echo ">>>>> Executing all LDAP tests for $BACKEND"
|
||||
|
||||
if [ -n "$NOEXIT" ]; then
|
||||
echo "Result Test" > $TESTWD/results
|
||||
fi
|
||||
|
||||
for CMD in ${SCRIPTDIR}/test*; do
|
||||
case "$CMD" in
|
||||
*~) continue;;
|
||||
*.bak) continue;;
|
||||
*.orig) continue;;
|
||||
*.sav) continue;;
|
||||
*.py) continue;;
|
||||
*) test -f "$CMD" || continue;;
|
||||
esac
|
||||
|
||||
# remove cruft from prior test
|
||||
if test $PRESERVE = yes ; then
|
||||
/bin/rm -rf $TESTDIR/db.*
|
||||
else
|
||||
/bin/rm -rf $TESTDIR
|
||||
fi
|
||||
|
||||
BCMD=`basename $CMD`
|
||||
if [ -x "$CMD" ]; then
|
||||
echo ">>>>> Starting ${TB}$BCMD${TN} for $BACKEND..."
|
||||
$CMD
|
||||
RC=$?
|
||||
if test $RC -eq 0 ; then
|
||||
echo ">>>>> $BCMD completed ${TB}OK${TN} for $BACKEND."
|
||||
else
|
||||
echo ">>>>> $BCMD ${TB}failed${TN} for $BACKEND"
|
||||
FAILCOUNT=`expr $FAILCOUNT + 1`
|
||||
|
||||
if [ -n "$NOEXIT" ]; then
|
||||
echo "Continuing."
|
||||
else
|
||||
echo "(exit $RC)"
|
||||
exit $RC
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo ">>>>> Skipping ${TB}$BCMD${TN} for $BACKEND."
|
||||
SKIPCOUNT=`expr $SKIPCOUNT + 1`
|
||||
RC="-"
|
||||
fi
|
||||
|
||||
if [ -n "$NOEXIT" ]; then
|
||||
echo "$RC $BCMD" >> $TESTWD/results
|
||||
fi
|
||||
|
||||
# echo ">>>>> waiting $SLEEPTIME seconds for things to exit"
|
||||
# sleep $SLEEPTIME
|
||||
echo ""
|
||||
done
|
||||
|
||||
if [ -n "$NOEXIT" ]; then
|
||||
if [ "$FAILCOUNT" -gt 0 ]; then
|
||||
cat $TESTWD/results
|
||||
echo "$FAILCOUNT tests for $BACKEND ${TB}failed${TN}. Please review the test log."
|
||||
else
|
||||
echo "All executed tests for $BACKEND ${TB}succeeded${TN}."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$SKIPCOUNT tests for $BACKEND were ${TB}skipped${TN}."
|
||||
105
contrib/slapd-modules/alias/tests/scripts/common.sh
Executable file
105
contrib/slapd-modules/alias/tests/scripts/common.sh
Executable file
|
|
@ -0,0 +1,105 @@
|
|||
#! /bin/sh
|
||||
## $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 2016-2023 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>.
|
||||
##
|
||||
## ACKNOWLEDGEMENTS:
|
||||
## This module was written in 2022 by Ondřej Kuzník for Symas Corp.
|
||||
|
||||
OVERLAY_CONFIG=${OVERLAY_CONFIG-data/config.ldif}
|
||||
|
||||
mkdir -p $TESTDIR $DBDIR1
|
||||
|
||||
echo "Running slapadd to build slapd database..."
|
||||
. $CONFFILTER $BACKEND $MONITORDB < $CONF > $ADDCONF
|
||||
$SLAPADD -f $ADDCONF -l $LDIF
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "slapadd failed ($RC)!"
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
mkdir $TESTDIR/confdir
|
||||
. $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1
|
||||
|
||||
$SLAPPASSWD -g -n >$CONFIGPWF
|
||||
echo "database config" >>$CONF1
|
||||
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF1
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT1 for configuration..."
|
||||
$SLAPD -f $CONF1 -F $TESTDIR/confdir -h $URI1 -d $LVL > $LOG1 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$PID"
|
||||
|
||||
sleep $SLEEP0
|
||||
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting ${SLEEP1} seconds for slapd to start..."
|
||||
sleep ${SLEEP1}
|
||||
done
|
||||
|
||||
$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
-s base -b 'cn=module{0},cn=config' 1.1 >$TESTOUT 2>&1
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
>> $TESTOUT 2>&1 <<EOMOD
|
||||
dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: `pwd`/../alias.la
|
||||
EOMOD
|
||||
;;
|
||||
32)
|
||||
$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
>> $TESTOUT 2>&1 <<EOMOD
|
||||
dn: cn=module,cn=config
|
||||
changetype: add
|
||||
objectClass: olcModuleList
|
||||
olcModuleLoad: `pwd`/../alias.la
|
||||
EOMOD
|
||||
;;
|
||||
*)
|
||||
echo "Failed testing for module load entry"
|
||||
exit $RC;
|
||||
;;
|
||||
esac
|
||||
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Loading test alias configuration..."
|
||||
. $CONFFILTER $BACKEND $MONITORDB < $OVERLAY_CONFIG | \
|
||||
$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
248
contrib/slapd-modules/alias/tests/scripts/test001-config
Executable file
248
contrib/slapd-modules/alias/tests/scripts/test001-config
Executable file
|
|
@ -0,0 +1,248 @@
|
|||
#! /bin/sh
|
||||
## $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 2016-2023 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>.
|
||||
##
|
||||
## ACKNOWLEDGEMENTS:
|
||||
## This module was written in 2023 by Ondřej Kuzník for Symas Corp.
|
||||
|
||||
echo "running defines.sh"
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
. ${SCRIPTDIR}/common.sh
|
||||
|
||||
echo "Applying invalid changes to config (should fail)..."
|
||||
for CHANGE in data/test001-*.ldif; do
|
||||
echo "... $CHANGE"
|
||||
. $CONFFILTER $BACKEND $MONITORDB < $CHANGE | \
|
||||
$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
>> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
echo "ldapmodify should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
;;
|
||||
17|19)
|
||||
echo "ldapmodify failed ($RC)"
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# We run this search after the changes above and before restart so we can also
|
||||
# check the reconfiguration attempts actually had no side effects
|
||||
echo "Saving search output before server restart..."
|
||||
echo "# search output from dynamically configured server..." >> $SERVER6OUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 \
|
||||
>> $SERVER6OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Stopping slapd on TCP/IP port $PORT1..."
|
||||
kill -HUP $KILLPIDS
|
||||
KILLPIDS=""
|
||||
sleep $SLEEP0
|
||||
echo "Starting slapd on TCP/IP port $PORT1..."
|
||||
$SLAPD -F $TESTDIR/confdir -h $URI1 -d $LVL >> $LOG1 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$PID"
|
||||
|
||||
sleep $SLEEP0
|
||||
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting ${SLEEP1} seconds for slapd to start..."
|
||||
sleep ${SLEEP1}
|
||||
done
|
||||
|
||||
echo "Testing slapd.conf support..."
|
||||
mkdir $TESTDIR/conftest $DBDIR2
|
||||
. $CONFFILTER $BACKEND $MONITORDB < $CONFTWO \
|
||||
| sed -e '/^argsfile.*/a\
|
||||
moduleload ../alias.la' \
|
||||
-e '/database.*monitor/i\
|
||||
include data/alias.conf' \
|
||||
> $CONF2
|
||||
echo "database config" >>$CONF2
|
||||
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF2
|
||||
|
||||
$SLAPADD -f $CONF2 -l $LDIFORDERED
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "slapadd failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT2..."
|
||||
$SLAPD -f $CONF2 -h $URI2 -d $LVL >> $LOG2 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
|
||||
sleep $SLEEP0
|
||||
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting ${SLEEP1} seconds for slapd to start..."
|
||||
sleep ${SLEEP1}
|
||||
done
|
||||
|
||||
echo "# search output from server running from slapd.conf..." >> $SERVER2OUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI2 \
|
||||
>> $SERVER2OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Stopping slapd on TCP/IP port $PORT2..."
|
||||
kill -HUP $PID
|
||||
|
||||
$SLAPD -Tt -f $CONF2 -F $TESTDIR/conftest -d $LVL >> $LOG3 2>&1
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT2..."
|
||||
$SLAPD -F $TESTDIR/conftest -h $URI2 -d $LVL >> $LOG3 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$KILLPIDS $PID"
|
||||
|
||||
sleep $SLEEP0
|
||||
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting ${SLEEP1} seconds for slapd to start..."
|
||||
sleep ${SLEEP1}
|
||||
done
|
||||
|
||||
echo "Gathering overlay configuration from both servers..."
|
||||
echo "# overlay configuration from dynamically configured server..." >> $SERVER1OUT
|
||||
$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
-b "olcOverlay={0}alias,olcDatabase={1}$BACKEND,cn=config" \
|
||||
| sed -e "s/ {[0-9]*}/ /" -e "s/={[0-9]*}/=/g" \
|
||||
>> $SERVER1OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "# overlay configuration from server configured from slapd.conf..." >> $SERVER3OUT
|
||||
$LDAPSEARCH -D cn=config -H $URI2 -y $CONFIGPWF \
|
||||
-b "olcOverlay={0}alias,olcDatabase={1}$BACKEND,cn=config" \
|
||||
| sed -e "s/ {[0-9]*}/ /" -e "s/={[0-9]*}/=/g" \
|
||||
>> $SERVER3OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
# We've already filtered out the ordering markers, now sort the entries
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER -s e < $SERVER3OUT > $SERVER3FLT
|
||||
echo "Filtering expected entries..."
|
||||
$LDIFFILTER -s e < $SERVER1OUT > $SERVER1FLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SERVER3FLT $SERVER1FLT > $CMPOUT
|
||||
|
||||
if test $? != 0 ; then
|
||||
echo "Comparison failed"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm $SERVER1OUT $SERVER3OUT
|
||||
|
||||
echo "Comparing search output on both servers..."
|
||||
echo "# search output from dynamically configured server..." >> $SERVER1OUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 \
|
||||
>> $SERVER1OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "# search output from server configured from slapd.conf..." >> $SERVER3OUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI2 \
|
||||
>> $SERVER3OUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER -s e < $SERVER1OUT > $SERVER1FLT
|
||||
$LDIFFILTER -s e < $SERVER2OUT > $SERVER2FLT
|
||||
$LDIFFILTER -s e < $SERVER3OUT > $SERVER3FLT
|
||||
echo "Filtering expected entries..."
|
||||
$LDIFFILTER -s e < $SERVER6OUT > $SERVER6FLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SERVER6FLT $SERVER1FLT > $CMPOUT && \
|
||||
$CMP $SERVER6FLT $SERVER2FLT > $CMPOUT && \
|
||||
$CMP $SERVER6FLT $SERVER3FLT > $CMPOUT
|
||||
|
||||
if test $? != 0 ; then
|
||||
echo "Comparison failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>>>> Test succeeded"
|
||||
|
||||
test $KILLSERVERS != no && wait
|
||||
|
||||
exit 0
|
||||
76
contrib/slapd-modules/alias/tests/scripts/test002-add-delete
Executable file
76
contrib/slapd-modules/alias/tests/scripts/test002-add-delete
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
#! /bin/sh
|
||||
## $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 2016-2023 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>.
|
||||
##
|
||||
## ACKNOWLEDGEMENTS:
|
||||
## This module was written in 2023 by Ondřej Kuzník for Symas Corp.
|
||||
|
||||
echo "running defines.sh"
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
. ${SCRIPTDIR}/common.sh
|
||||
|
||||
echo "Applying changes affecting aliased attribute (should fail)..."
|
||||
for CHANGE in data/test002-*.ldif; do
|
||||
echo "... $CHANGE"
|
||||
$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
|
||||
-f $CHANGE >> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
echo "ldapmodify should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
;;
|
||||
19)
|
||||
echo "ldapmodify failed ($RC)"
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Saving search output..."
|
||||
# We're just making sure no modifications made it to the DB, bypass
|
||||
# the overlay to be able to compare with ldif used to populate it.
|
||||
$LDAPSEARCH -M -b "$BASEDN" -H $URI1 >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
|
||||
echo "Filtering expected entries..."
|
||||
$LDIFFILTER -s e < $LDIF > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
if test $? != 0 ; then
|
||||
echo "Comparison failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>>>> Test succeeded"
|
||||
|
||||
test $KILLSERVERS != no && wait
|
||||
|
||||
exit 0
|
||||
151
contrib/slapd-modules/alias/tests/scripts/test003-search
Executable file
151
contrib/slapd-modules/alias/tests/scripts/test003-search
Executable file
|
|
@ -0,0 +1,151 @@
|
|||
#! /bin/sh
|
||||
## $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 2016-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>.
|
||||
##
|
||||
## ACKNOWLEDGEMENTS:
|
||||
## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
|
||||
|
||||
echo "running defines.sh"
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
. ${SCRIPTDIR}/common.sh
|
||||
|
||||
echo "Comparing aliased attribute..."
|
||||
$LDAPCOMPARE -H $URI1 \
|
||||
"cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN" \
|
||||
"mobile:+1 313 555 7671" >> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 6 && test $RC,$BACKEND != 5,null ; then
|
||||
echo "ldapcompare failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$LDAPCOMPARE -H $URI1 \
|
||||
"cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN" \
|
||||
"mobile:+1 313 555 4177" >> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 5 ; then
|
||||
echo "ldapcompare should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Listing alias attribute specifically..."
|
||||
echo "# Listing aliased attribute..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 "uid=bjensen" mobile \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Not asking for alias attribute..."
|
||||
echo >> $SEARCHOUT
|
||||
echo "# A search when aliased attribute is not requested..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 "uid=bjensen" pager \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Retrieving both the aliased attribute and the source..."
|
||||
echo >> $SEARCHOUT
|
||||
echo "# A search when both are requested (explicitly)..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 "uid=bjensen" mobile pager \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Retrieving both the aliased attribute and the source..."
|
||||
echo >> $SEARCHOUT
|
||||
echo "# A search when both are requested (implicitly)..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 "uid=bjensen" \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Testing searches filtering on aliased attributes..."
|
||||
echo >> $SEARCHOUT
|
||||
echo "# Testing searches filtering on aliased attributes..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 \
|
||||
"(|(mobile=+1 313 555 3233)(mobile=*4474)(&(mobile=*)(uid=jdoe)))" \
|
||||
mobile \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Reconfiguring alias definition..."
|
||||
. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
|
||||
$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
|
||||
>> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Testing searches with new attributes..."
|
||||
echo >> $SEARCHOUT
|
||||
echo "# Testing search with new attributes..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -b "$BASEDN" -H $URI1 \
|
||||
"employeetype=*director*" \
|
||||
employeetype mobile \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
LDIF=data/test003-out.ldif
|
||||
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
|
||||
echo "Filtering expected entries..."
|
||||
$LDIFFILTER -s e < $LDIF > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
if test $? != 0 ; then
|
||||
echo "Comparison failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>>>> Test succeeded"
|
||||
|
||||
test $KILLSERVERS != no && wait
|
||||
|
||||
exit 0
|
||||
Loading…
Reference in a new issue