Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
openldap
OpenLDAP
Commits
b6208a44
Commit
b6208a44
authored
Jul 03, 2015
by
Howard Chu
Browse files
New ADremap overlay
parent
e4278b57
Changes
4
Hide whitespace changes
Inline
Side-by-side
contrib/ConfigOIDs
View file @
b6208a44
...
...
@@ -5,3 +5,4 @@ OLcfgCt{Oc|At}:2 autogroup
OLcfgCt{Oc|At}:3 nssov
OLcfgCt{Oc|At}:4 cloak
OLcfgCt{Oc|At}:5 lastbind
OLcfgCt{Oc|At}:6 adremap
contrib/slapd-modules/adremap/Makefile
0 → 100644
View file @
b6208a44
# $OpenLDAP$
# Copyright 2015 Howard Chu <hyc@symas.com>
# 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)
LDAP_INC
=
-I
$(LDAP_BUILD)
/include
-I
$(LDAP_SRC)
/include
-I
$(LDAP_SRC)
/servers/slapd
LDAP_LIB
=
$(LDAP_BUILD)
/libraries/libldap_r/libldap_r.la
\
$(LDAP_BUILD)
/libraries/liblber/liblber.la
LIBTOOL
=
$(LDAP_BUILD)
/libtool
CC
=
gcc
OPT
=
-g
-O2
-Wall
DEFS
=
-DSLAPD_OVER_ADREMAP
=
SLAPD_MOD_DYNAMIC
INCS
=
$(LDAP_INC)
LIBS
=
$(LDAP_LIB)
PROGRAMS
=
adremap.la
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)
.SUFFIXES
:
.c .o .lo
.c.lo
:
$(LIBTOOL)
--mode
=
compile
$(CC)
$(OPT)
$(DEFS)
$(INCS)
-c
$<
all
:
$(PROGRAMS)
adremap.la
:
adremap.lo
$(LIBTOOL)
--mode
=
link
$(CC)
$(OPT)
-version-info
$(LTVER)
\
-rpath
$(moduledir)
-module
-o
$@
$?
$(LIBS)
clean
:
rm
-rf
*
.o
*
.lo
*
.la .libs
install
:
$(PROGRAMS)
mkdir
-p
$(DESTDIR)$(moduledir)
for
p
in
$(PROGRAMS)
;
do
\
$(LIBTOOL)
--mode
=
install cp
$$
p
$(DESTDIR)$(moduledir)
;
\
done
contrib/slapd-modules/adremap/adremap.c
0 → 100644
View file @
b6208a44
/* adremap.c - Case-folding and DN-value remapping for AD proxies */
/* $OpenLDAP$ */
/*
* Copyright 2015 Howard Chu <hyc@symas.com>.
* 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>.
*/
#include
"portable.h"
/*
* This file implements an overlay that performs two remapping functions
* to allow older POSIX clients to use Microsoft AD:
* 1: downcase the values of a configurable list of attributes
* 2: dereference some DN-valued attributes and convert to their simple names
* e.g. generate memberUid based on member
*/
#ifdef SLAPD_OVER_ADREMAP
#include
<ldap.h>
#include
"lutil.h"
#include
"slap.h"
#include
<ac/errno.h>
#include
<ac/time.h>
#include
<ac/string.h>
#include
<ac/ctype.h>
#include
"config.h"
typedef
struct
adremap_dnv
{
struct
adremap_dnv
*
ad_next
;
AttributeDescription
*
ad_dnattr
;
/* DN-valued attr to deref */
AttributeDescription
*
ad_deref
;
/* target attr's value to retrieve */
AttributeDescription
*
ad_newattr
;
/* New attr to collect new values */
}
adremap_dnv
;
/* example: member uid memberUid */
typedef
struct
adremap_case
{
struct
adremap_case
*
ac_next
;
AttributeDescription
*
ac_attr
;
}
adremap_case
;
/* Per-instance configuration information */
typedef
struct
adremap_info
{
adremap_case
*
ai_case
;
/* attrs to downcase */
adremap_dnv
*
ai_dnv
;
/* DN attrs to remap */
}
adremap_info
;
enum
{
ADREMAP_CASE
=
1
,
ADREMAP_DNV
};
static
ConfigDriver
adremap_cf_case
;
static
ConfigDriver
adremap_cf_dnv
;
/* configuration attribute and objectclass */
static
ConfigTable
adremapcfg
[]
=
{
{
"adremap-downcase"
,
"attrs"
,
2
,
0
,
0
,
ARG_MAGIC
|
ADREMAP_CASE
,
adremap_cf_case
,
"( OLcfgCtAt:6.1 "
"NAME 'olcADremapDowncase' "
"DESC 'List of attributes to casefold to lower case' "
"SYNTAX OMsDirectoryString )"
,
NULL
,
NULL
},
{
"adremap-dnmap"
,
"dnattr simpleattr newattr"
,
4
,
4
,
0
,
ARG_MAGIC
|
ADREMAP_DNV
,
adremap_cf_dnv
,
"( OLcfgCtAt:6.2 "
"NAME 'olcADremapDNmap' "
"DESC 'DN attr to map, attr from target to use, attr to generate' "
"SYNTAX OMsDirectoryString )"
,
NULL
,
NULL
},
{
NULL
,
NULL
,
0
,
0
,
0
,
ARG_IGNORED
}
};
static
ConfigOCs
adremapocs
[]
=
{
{
"( OLcfgCtOc:6.1 "
"NAME 'olcADremapConfig' "
"DESC 'AD remap configuration' "
"SUP olcOverlayConfig "
"MAY ( olcADremapDowncase $ olcADremapDNmap ) )"
,
Cft_Overlay
,
adremapcfg
,
NULL
,
NULL
},
{
NULL
,
0
,
NULL
}
};
static
int
adremap_cf_case
(
ConfigArgs
*
c
)
{
BackendDB
*
be
=
(
BackendDB
*
)
c
->
be
;
slap_overinst
*
on
=
(
slap_overinst
*
)
c
->
bi
;
adremap_info
*
ai
=
on
->
on_bi
.
bi_private
;
adremap_case
*
ac
,
**
a2
;
int
rc
=
ARG_BAD_CONF
;
switch
(
c
->
op
)
{
case
SLAP_CONFIG_EMIT
:
for
(
ac
=
ai
->
ai_case
;
ac
;
ac
=
ac
->
ac_next
)
{
rc
=
value_add_one
(
&
c
->
rvalue_vals
,
&
ac
->
ac_attr
->
ad_cname
);
if
(
rc
)
break
;
}
break
;
case
LDAP_MOD_DELETE
:
if
(
c
->
valx
<
0
)
{
for
(
ac
=
ai
->
ai_case
;
ac
;
ac
=
ai
->
ai_case
)
{
ai
->
ai_case
=
ac
->
ac_next
;
ch_free
(
ac
);
}
}
else
{
int
i
;
for
(
i
=
0
,
a2
=
&
ai
->
ai_case
;
i
<
c
->
valx
;
i
++
,
a2
=
&
(
*
a2
)
->
ac_next
);
ac
=
*
a2
;
*
a2
=
ac
->
ac_next
;
ch_free
(
ac
);
}
rc
=
0
;
break
;
default:
{
const
char
*
text
;
adremap_case
ad
;
ad
.
ac_attr
=
NULL
;
rc
=
slap_str2ad
(
c
->
argv
[
1
],
&
ad
.
ac_attr
,
&
text
);
if
(
rc
)
break
;
for
(
a2
=
&
ai
->
ai_case
;
*
a2
;
a2
=
&
(
*
a2
)
->
ac_next
);
ac
=
ch_malloc
(
sizeof
(
adremap_case
));
ac
->
ac_next
=
NULL
;
ac
->
ac_attr
=
ad
.
ac_attr
;
*
a2
=
ac
;
break
;
}
}
return
rc
;
}
static
int
adremap_cf_dnv
(
ConfigArgs
*
c
)
{
BackendDB
*
be
=
(
BackendDB
*
)
c
->
be
;
slap_overinst
*
on
=
(
slap_overinst
*
)
c
->
bi
;
adremap_info
*
ai
=
on
->
on_bi
.
bi_private
;
adremap_dnv
*
ad
,
**
a2
;
int
rc
=
ARG_BAD_CONF
;
switch
(
c
->
op
)
{
case
SLAP_CONFIG_EMIT
:
for
(
ad
=
ai
->
ai_dnv
;
ad
;
ad
=
ad
->
ad_next
)
{
char
*
ptr
;
struct
berval
bv
;
bv
.
bv_len
=
ad
->
ad_dnattr
->
ad_cname
.
bv_len
+
ad
->
ad_deref
->
ad_cname
.
bv_len
+
ad
->
ad_newattr
->
ad_cname
.
bv_len
+
2
;
bv
.
bv_val
=
ch_malloc
(
bv
.
bv_len
+
1
);
ptr
=
lutil_strcopy
(
bv
.
bv_val
,
ad
->
ad_dnattr
->
ad_cname
.
bv_val
);
*
ptr
++
=
' '
;
ptr
=
lutil_strcopy
(
ptr
,
ad
->
ad_deref
->
ad_cname
.
bv_val
);
*
ptr
++
=
' '
;
strcpy
(
ptr
,
ad
->
ad_newattr
->
ad_cname
.
bv_val
);
ber_bvarray_add
(
&
c
->
rvalue_vals
,
&
bv
);
}
if
(
ai
->
ai_dnv
)
rc
=
0
;
break
;
case
LDAP_MOD_DELETE
:
if
(
c
->
valx
<
0
)
{
for
(
ad
=
ai
->
ai_dnv
;
ad
;
ad
=
ai
->
ai_dnv
)
{
ai
->
ai_dnv
=
ad
->
ad_next
;
ch_free
(
ad
);
}
}
else
{
int
i
;
for
(
i
=
0
,
a2
=
&
ai
->
ai_dnv
;
i
<
c
->
valx
;
i
++
,
a2
=
&
(
*
a2
)
->
ad_next
);
ad
=
*
a2
;
*
a2
=
ad
->
ad_next
;
ch_free
(
ad
);
}
rc
=
0
;
break
;
default:
{
const
char
*
text
;
adremap_dnv
av
=
{
0
};
rc
=
slap_str2ad
(
c
->
argv
[
1
],
&
av
.
ad_dnattr
,
&
text
);
if
(
rc
)
break
;
if
(
av
.
ad_dnattr
->
ad_type
->
sat_syntax
!=
slap_schema
.
si_syn_distinguishedName
)
{
rc
=
1
;
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
"<%s> not a DN-valued attribute"
,
c
->
argv
[
0
]);
Debug
(
LDAP_DEBUG_ANY
,
"%s: %s(%s)
\n
"
,
c
->
log
,
c
->
cr_msg
,
c
->
argv
[
1
]);
break
;
}
rc
=
slap_str2ad
(
c
->
argv
[
2
],
&
av
.
ad_deref
,
&
text
);
if
(
rc
)
break
;
rc
=
slap_str2ad
(
c
->
argv
[
3
],
&
av
.
ad_newattr
,
&
text
);
if
(
rc
)
break
;
for
(
a2
=
&
ai
->
ai_dnv
;
*
a2
;
a2
=
&
(
*
a2
)
->
ad_next
);
ad
=
ch_malloc
(
sizeof
(
adremap_dnv
));
ad
->
ad_next
=
NULL
;
ad
->
ad_dnattr
=
av
.
ad_dnattr
;
ad
->
ad_deref
=
av
.
ad_deref
;
ad
->
ad_newattr
=
av
.
ad_newattr
;
*
a2
=
ad
;
break
;
}
}
return
rc
;
}
static
int
adremap_search_resp
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
op
->
o_callback
->
sc_private
;
adremap_info
*
ai
=
on
->
on_bi
.
bi_private
;
adremap_case
*
ac
;
adremap_dnv
*
ad
;
Attribute
*
a
;
Entry
*
e
;
if
(
rs
->
sr_type
!=
REP_SEARCH
)
return
SLAP_CB_CONTINUE
;
e
=
rs
->
sr_entry
;
for
(
ac
=
ai
->
ai_case
;
ac
;
ac
=
ac
->
ac_next
)
{
a
=
attr_find
(
e
->
e_attrs
,
ac
->
ac_attr
);
if
(
a
)
{
int
i
,
j
;
if
(
!
(
rs
->
sr_flags
&
REP_ENTRY_MODIFIABLE
))
{
e
=
entry_dup
(
e
);
rs_replace_entry
(
op
,
rs
,
on
,
e
);
rs
->
sr_flags
|=
REP_ENTRY_MODIFIABLE
|
REP_ENTRY_MUSTBEFREED
;
a
=
attr_find
(
e
->
e_attrs
,
ac
->
ac_attr
);
}
for
(
i
=
0
;
i
<
a
->
a_numvals
;
i
++
)
{
unsigned
char
*
c
=
a
->
a_vals
[
i
].
bv_val
;
for
(
j
=
0
;
j
<
a
->
a_vals
[
i
].
bv_len
;
j
++
)
if
(
isupper
(
c
[
j
]))
c
[
j
]
=
tolower
(
c
[
j
]);
}
}
}
for
(
ad
=
ai
->
ai_dnv
;
ad
;
ad
=
ad
->
ad_next
)
{
a
=
attr_find
(
e
->
e_attrs
,
ad
->
ad_dnattr
);
if
(
a
)
{
Entry
*
n
;
Attribute
*
dr
;
int
i
,
rc
;
if
(
!
(
rs
->
sr_flags
&
REP_ENTRY_MODIFIABLE
))
{
e
=
entry_dup
(
e
);
rs_replace_entry
(
op
,
rs
,
on
,
e
);
rs
->
sr_flags
|=
REP_ENTRY_MODIFIABLE
|
REP_ENTRY_MUSTBEFREED
;
a
=
attr_find
(
e
->
e_attrs
,
ad
->
ad_dnattr
);
}
for
(
i
=
0
;
i
<
a
->
a_numvals
;
i
++
)
{
n
=
NULL
;
rc
=
be_entry_get_rw
(
op
,
&
a
->
a_nvals
[
i
],
NULL
,
ad
->
ad_deref
,
0
,
&
n
);
if
(
!
rc
&&
n
)
{
dr
=
attr_find
(
n
->
e_attrs
,
ad
->
ad_deref
);
if
(
dr
)
attr_merge_one
(
e
,
ad
->
ad_newattr
,
dr
->
a_vals
,
dr
->
a_nvals
);
be_entry_release_r
(
op
,
n
);
}
}
}
}
return
SLAP_CB_CONTINUE
;
}
static
int
adremap_search
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
slap_callback
*
cb
;
cb
=
op
->
o_tmpcalloc
(
1
,
sizeof
(
slap_callback
),
op
->
o_tmpmemctx
);
cb
->
sc_response
=
adremap_search_resp
;
cb
->
sc_private
=
on
;
cb
->
sc_next
=
op
->
o_callback
;
op
->
o_callback
=
cb
;
return
SLAP_CB_CONTINUE
;
}
static
int
adremap_db_init
(
BackendDB
*
be
,
ConfigReply
*
cr
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
be
->
bd_info
;
/* initialize private structure to store configuration */
on
->
on_bi
.
bi_private
=
ch_calloc
(
1
,
sizeof
(
adremap_info
)
);
return
0
;
}
static
int
adremap_db_destroy
(
BackendDB
*
be
,
ConfigReply
*
cr
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
be
->
bd_info
;
adremap_info
*
ai
=
(
adremap_info
*
)
on
->
on_bi
.
bi_private
;
adremap_case
*
ac
;
adremap_dnv
*
ad
;
/* free config */
for
(
ac
=
ai
->
ai_case
;
ac
;
ac
=
ai
->
ai_case
)
{
ai
->
ai_case
=
ac
->
ac_next
;
ch_free
(
ac
);
}
for
(
ad
=
ai
->
ai_dnv
;
ad
;
ad
=
ai
->
ai_dnv
)
{
ai
->
ai_dnv
=
ad
->
ad_next
;
ch_free
(
ad
);
}
free
(
ai
);
return
0
;
}
static
slap_overinst
adremap
;
int
adremap_initialize
()
{
int
i
,
code
;
adremap
.
on_bi
.
bi_type
=
"adremap"
;
adremap
.
on_bi
.
bi_db_init
=
adremap_db_init
;
adremap
.
on_bi
.
bi_db_destroy
=
adremap_db_destroy
;
adremap
.
on_bi
.
bi_op_search
=
adremap_search
;
/* register configuration directives */
adremap
.
on_bi
.
bi_cf_ocs
=
adremapocs
;
code
=
config_register_schema
(
adremapcfg
,
adremapocs
);
if
(
code
)
return
code
;
return
overlay_register
(
&
adremap
);
}
#if SLAPD_OVER_ADREMAP == SLAPD_MOD_DYNAMIC
int
init_module
(
int
argc
,
char
*
argv
[])
{
return
adremap_initialize
();
}
#endif
#endif
/* defined(SLAPD_OVER_ADREMAP) */
contrib/slapd-modules/adremap/slapo-adremap.5
0 → 100644
View file @
b6208a44
.TH SLAPO-ADREMAP 5 "RELEASEDATE" "OpenLDAP LDVERSION"
.\" Copyright 2015 Howard Chu, All Rights Reserved.
.\" $OpenLDAP$
.SH NAME
slapo-adremap \- AD Remap overlay to slapd
.SH SYNOPSIS
ETCDIR/slapd.conf
.SH DESCRIPTION
The
.B adremap
overlay to
.BR slapd (8)
remaps some attribute values for compatibility between Microsoft AD
and older POSIX systems' PAM/NSS clients. It can be configured to
convert values of given attributes to lower case, and it can be
configured to generate RFC2307-compliant group memberships based
on RFC2307bis groups. All mapping is only performed on entries
returned as search responses.
.SH CONFIGURATION
The config directives that are specific to the
.B adremap
overlay must be prefixed by
.BR adremap\- ,
to avoid potential conflicts with directives specific to the underlying
database or to other stacked overlays.
.TP
.B overlay adremap
This directive adds the
.B adremap
overlay to the current database, see
.BR slapd.conf (5)
for details.
.LP
These
.B slapd.conf
configuration options are defined for the adremap overlay. They must
appear after the
.B overlay
directive. They can each be specified multiple times:
.TP
.B adremap-downcase <attr>
Specify an attributeType whose values will all be mapped to lowercase
when returned in search responses.
.TP
.B adremap-dnmap <dnattr> <derefattr> <newattr>
Specify a DN-valued attributeType whose values will be dereferenced. The
.B <derefattr>
of the target entry will be retrieved and its value will be added to the
.B <newattr>
in the entry.
.SH EXAMPLE
This example configures the
.B adremap
overlay to map all
.B uid
attributes to lowercase, and create
.B memberUid
values for group entries.
Add the following to
.BR slapd.conf (5):
.LP
.nf
database <database>
# ...
overlay adremap
adremap-downcase uid
adremap-dnmap member uid memberUid
.fi
.LP
.B slapd
must also load
.B adremap.la,
if compiled as a run-time module;
.SH FILES
.TP
ETCDIR/slapd.conf
default slapd configuration file
.SH SEE ALSO
.BR slapd.conf (5),
.BR slapd (8).
The
.BR slapo-adremap (5)
overlay supports dynamic configuration via
.BR back-config.
.SH ACKNOWLEDGEMENTS
.P
This module was written in 2015 by Howard Chu.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment