Optionally, if you need an interface to query your LDAP directory and display the results in a topic install the LdapNgPlugin which will make use of the LdapContrib services. This work is a rewrite of the LdapPlugin by Gerard Hickey while bringing authentication, user management and other LDAP applications onto a common base.
This package downloads all relevant records from your LDAP server into a local cache the first time you use it. This can take a noticeable period of time depending on the size of your LDAP database. This cache will be refreshed on a configurable interval (defaults to once a day). You can also disable automatic refreshing and refresh the LdapContrib's cache manually using the "Refresh Cache" button below. Read the documentation ofMaxCacheAge
in the section
"Performance Settings" in configure.
Refresh Cache
Tip: You can add this button on any page by adding
%INCLUDE{"%SYSTEMWEB%.LdapContrib" section="refreshbutton"}%
to it.
dc=my,dc=domain,dc=com
)?
ou=people,dc=my,dc=domain,dc=com
or are they are scattered all over the place?
objectClass=organizationalPerson
)?
objectClass=group
)?
Collect the answers to these questions either yourself using your favorite LDAP browser, or ask your friendly LDAP admin.
lib/LocalSite.cfg
configuration file (or by using the configure
tool alternatively):
$Foswiki::cfg{PasswordManager} = 'Foswiki::Users::LdapPasswdUser';
There is a further option to fallback to the normal authentication mechanism by defining a secondary password manager. This allows you to create native wiki accounts, e.g. a WikiAdmin account and authenticate him without LDAP. Use the following setting to fallback to a htpasswd based authentication.
$Foswiki::cfg{Ldap}{SecondaryPasswordManager} = 'Foswiki::Users::HtPasswdUser';
So whenever authentication against LDAP fails, this second password manager will be used.
lib/LocalSite.cfg
configuration file (or by using the configure
tool alternatively):
$Foswiki::cfg{UserMappingManager} = 'Foswiki::Users::LdapUserMapping';In addition you can decide if you want to add the LDAP groups or use LDAP groups solely. This is controlled by the WikiGroupsBackoff flag. If switched on then LDAP groups will be added. If there's a name clash LDAP groups take precedence. If switched off WikiGroups are ignored. You might decide in not using your LDAP groups but still map login names to WikiNames. Both, LDAP user groups and name mapping is done by the UserMappingManager. So to make use of name mapping but not its group feature, register the LdapUserMapping implementation for the UserMappingManager but disable the MapGroups setting. When multiple groups in your LDAP directory clash on the same group name you might actually wish to merge these groups as used online in your wiki. This is done using the
MergeGroups
flag. When disabled, clashing groups
are reported as a warning in the server log files when the LDAP cache is
refreshed.
MemberIndirection
setting.
The reverse relation, where the user objects hold membership information
(for example using a memberOf
attribute) is
maintained by some LDAP servers automatically. Those that encode membership this
way only are not supported by the LdapContrib yet.
Furthermore, user objects may have one primary group attribute.
This is a simple value that stores the id of a default group
that user is member of. This attribute is defined by specifying the PrimaryGroupAttribute
setting a.
LdapContrib reads membership information as they are stored in the group objects, and may map the member object indirectly to the login name. In addition any "primary group" setting stored in the user objects is consulted as well.
The WikiName can be generated by setting the parameters
WikiNameAttributes
: a comma sedparated list of LDAP attributes taht are then assembled to form a proper WikiName
NormalizeWikiName
: boolean flag; if set a couple of extra operations are performed to generate a proper WikiName, i.e. removing illegal characters.
WikiNameAliases
: a comma separated key=value list of WikiNames to be mapped to another WikiName (DEPRECATED: use RewriteWikiNames
instead).
RewriteWikiNames
: a list of rewrite rules; see below
UserMappingTopic
: a topic that holds a pre-defined login-to-wikiname mapping; this comes in handy when migrating from a TopicUserMapping to an LDAP setup where names already in use should be preserved. Note that no rewrite or normalization is applied if a login name is found in the database
Given the setting
$Foswiki::cfg{Ldap}{WikiNameAttributes} = 'givenName,sn'; $Foswiki::cfg{Ldap}{NormalizeWikiNames} = 1;The
givenName
and sn
(surname) LDAP attributes will be fetched and concatenated
to form a proper WikiName, so that "givenName=Hans-Peter,sn=Schwarze" will
result in the WikiName "HansPeterSchwarze".
The login name can be normalized by enabling the
$Foswiki::cfg{Ldap}{NormalizeLoginNames} = 1;
setting. This will also strip off any '@...' string from the login as found when logging ing using the mail attribute or when using LdapContrib in combination with a kerberos single sign on strategy.
In most scenarios users prefer not to care about case sensitivity of their login names for convenience. If however your authentication requires an exact match of the login name including case sensitivity, the use
$Foswiki::cfg{Ldap}{CaseSensitiveLogin} = 1;
to switch that on.
Similar to the WikiName of a user, group names can be normalized using
$Foswiki::cfg{Ldap}{NormalizeGroupNames} = 1;
If a user in your LDAP directory changed his name, e.g. because of a marriage, this use can be mapped to his/her old account using an alias that points back from the old WikiName to the new one. This is done using a setting like this:
$Foswiki::cfg{Ldap}{WikiNameAliases} = 'MaryMalone=MaryForrester, ...'The parameter takes a comma separated list of
FromWikiName=ToWikiName
. Whenever
this account is still used in an access control list, its rights will be
inherited by the targeted ToWikiName
account.
Group names can be rewritten using a set of rewrite rules. This is useful when the names as stored in your LDAP directory don't satisfy your criteria for being displayed online. In conjunction with the MergeGroups flag, separate LDAP groups can be merged onto one group as it is used online in your wiki.
A group rewrite rule is specified using
$Foswiki::cfg{Ldap}{RewriteGroups} = { 'pattern1' => 'substitution1', 'pattern2' => 'substitution2', ... };Each rule consists of a pattern that will be substituted in the group name as specified. The substitute can contain variables
$1
, $2
, … , $5
to insert the first, second, …, fifth
bracket pair in the key pattern. (see perl manual for regular expressions).
Example:
$Foswiki::cfg{Ldap}{RewriteGroups} = { '(.*)_users' => '$1' };WikiNames can be processed similarly using the
$Foswiki::cfg{Ldap}{RewriteWikiNames}
parameter. Given the WikiName is derived from the mail attribute, then use the following
rule to strip off domain parts from the wiki name:
$Foswiki::cfg{Ldap}{RewriteWikiNames} = { '^(.*)@.*$' => '$1' };
This can be further refined to prevent name clashes by adding back the domain part:
$Foswiki::cfg{Ldap}{RewriteWikiNames} = { '^(.*)@(.*?)\..*\..*$' => '$1_$2' };
So given your company uses email addresses like john.doe@germany.mycompany.com and john.doe@spain.mycompany.com it will generate the wiki names JohnDoeGermany and JohnDoeSpain from it (given NormalizeWikiNames is switched on too).
Another trick is to add additional LDAP attributes to theWikiNameAttributes
that
help to create unique WikiNames, and then strip off unwanted parts again
with an appropriate rewrite rule.
Example:
$Foswiki::cfg{Ldap}{WikiNameAttributes} = 'givenName, sn, sAMAccountName'; $Foswiki::cfg{Ldap}{RewriteWikiNames} = { '^(.*) [^ ]+?\-adm$' => '$1 Admin', '^(.*) (?!\-adm$)[^ ]+?$' => '$1', }
This might look wild at first but does the following:
WikiNameAttributes
setting, e.g. "John-Doe Smith jds", where jds is the sAMAccountName value
jds-adm
login.
RewriteWikiNames
will match the jds-adm
and will generate a nice John-Doe Smith Admin, whereas
-adm
suffic at their sAMAccountName.
WikiNameAttributes
and RewriteWikiNames
rules your LDAP records will be mapped
onto a proper WikiName. These have to be unique to represent the identity of the person granted access to Foswiki.
However, while you LDAP records are unique
due to their Distinguished Names, it is quite common that two independent records result in the
same WikiName. That's a so called name clash. You are strongly encouraged to control the way
WikiNames are generated to keep the number of name clashes as low as possible. Use appropriate
rewrite rues as described above.
In real world you will most probalby run into a name clash that you can't possibly resolve. In that case
LdapContrib will enumerate all JohnSmiths as they are found, calling them JohnSmith, JohnSmith1, JohnSmith2, etc.
Each of these maps back to a unique Distinguished Name in your LDAP directory of course.
LdapContrib tries to keep the choice which of the JohnSmiths maps to which DN stable over time. Whenever you refresh the LDAP cache the previous WikiNames will be reused while new LDAP records will get a higher number attached to the WikiName.
When LdapContrib is building up its cache for the first time, the actual mapping is pretty arbitrary, given there are no additional means to distinguish the names. From there on WikiNames are kept, even when you reconfigure LdapContrib itself. This is the default behavior not to risk mapping a different identity to a WikiName. You still might decide to nuke the decisions once made while resolving name clashes by refreshing the ldap cache using therefreshldap=force
url parameter (compared to refreshldap=on
to up the cache regularly).
Note doing this later in the life time of your wiki might accidentally swap the mapping of LDAP records
to WikiNames in case they clash. So be very cautious when doing that.
KerberosLogin
manager depends on CPAN:GSSAPI and requires Foswiki >= 2.0.0
{Ldap}{KerberosKeyTab}
(defaults to /etc/krb5.keytab
).
The LoginManager must be set to KerberosLogin
.
Foswiki will then initiate the negotiation process with the user's
browser so that it submits an authentication token on the base of the user's kerberos ticket.
The authentication token will then be used to derive the login name of the user automatically.
LdapContrib is then used to complete an LDAP integration by mapping the login name to the WikiName, email information and group membership gathered from the LDAP directory directly.
Note that the negotioation process will only be initiated either on access-restricted resources, or by visiting the Login url. When no valid kerberos ticket is available on the client side will the authentication fall back to a template based login to enter credentials manually as if theTemplateLogin
LoginManager
has been used.
posixAccount
and optionally also of type
inetOrgPerson
storing email addresses. Moreover users are stored in a subtree
ou=people
and groups are defined in ou=group
. Here are some example LDAP
records:
dn: uid=testuser1,ou=people,dc=my,dc=domain,dc=com objectClass: inetOrgPerson objectClass: posixAccount cn: Test User1 uid: testuser1 uidNumber: 1024 gidNumber: 100 homeDirectory: /home/testuser1 loginShell: /bin/bash mail: testuser1@my.domain.com dn: uid=testuser2,ou=people,dc=my,dc=domain,dc=com objectClass: inetOrgPerson objectClass: posixAccount cn: Test User2 uid: testuser2 uidNumber: 1024 gidNumber: 100 homeDirectory: /home/testuser2 loginShell: /bin/bash mail: testuser2@my.domain.com mail: testuser2@gmx.com # users, Group, nats.informatik.uni-hamburg.de dn: cn=users,ou=group,dc=my,dc=domain,dc=com objectClass: posixGroup cn: users gidNumber: 100 memberUid: testuser1 memberUid: testuser2Please have a look at your LDAP manual on how to set up an LDAP server and populate it with user account records. Have a look at the Quick-Start Guide on how to install OpenLdap.
Use the following settings for the above example:
$Foswiki::cfg{Ldap}{Host} = 'ldap.my.domain.com'; $Foswiki::cfg{Ldap}{Port} = 389; $Foswiki::cfg{Ldap}{UserBase} = ['ou=people,dc=my,dc=domain,dc=com']; $Foswiki::cfg{Ldap}{LoginFilter} = 'objectClass=posixAccount'; $Foswiki::cfg{Ldap}{LoginAttribute} = 'uid'; $Foswiki::cfg{Ldap}{WikiNameAttributes} = 'cn'; $Foswiki::cfg{Ldap}{NormalizeWikiNames} = 1; $Foswiki::cfg{Ldap}{GroupBase} = ['ou=group,dc=my,dc=domain,dc=com']; $Foswiki::cfg{Ldap}{GroupFilter} = 'objectClass=posixGroup'; $Foswiki::cfg{Ldap}{GroupAttribute} = 'cn'; $Foswiki::cfg{Ldap}{MemberAttribute} = 'memberUid'; $Foswiki::cfg{Ldap}{MemberIndirection} = 0; $Foswiki::cfg{Ldap}{MapGroups} = 1;
$Foswiki::cfg{Ldap}{Host} = 'ldaps://ldap.my.domain.com'; $Foswiki::cfg{Ldap}{Port} = 636; $Foswiki::cfg{Ldap}{TLSCAPath} = '/etc/openldap/cacerts/'; $Foswiki::cfg{Ldap}{TLSCAFile} = 'cer.pem'; $Foswiki::cfg{Ldap}{TLSClientCert} = 'cer.pem'; $Foswiki::cfg{Ldap}{TLSClientKey} = 'cer.key';
lib/LocalSite.cfg
configuration file.
Use the configure tool (at least
once) after you installed this package. Have a look at your lib/LocalSite.cfg
file afterwards. You might also make your changes therein directly to
accommodate your installation to your specific LDAP installation and user
accounting. See the documentation within the configure
tool for an explanation
of the various options.
MaxCacheAge
setting. This setting defaults to updating the
cache every 24 hours. The refresh procedure will then be triggered by the first request
that hits the site when this period expired.
To remove this burden from the "first visitor in the morning", the automatic refresh procedure can be disabled by setting
$Foswiki::cfg{Ldap}{MaxCacheAge} = 0;This means that the age of the cached data will not be checked automatically anymore. The responsibility that the data is updated is now up to you, that is you have to update the cache explicitly. This can be done by either hitting the red "Refresh Cache" button above, or by setting up an appropriate cronjob on the machine running your wiki server.
To trigger an explicit update of the cache on 5 past midnight every day use a cronjob similar to:
5 0 * * * cd <wiki-install-path>/bin && ./view refreshldap=on Main/WebHome >/dev/null
This will call the engine on the command line and provide the necessary query parameters so that the LdapContrib will force an update of the cache data.
{Ldap}{Debug}
in configure
and analyze the output as generated in the error.log file of your web server. Try to
examine the output as generated by (a) a normal access to the site versus (b) a refresh
of the
LDAP cache. There should be sufficient information in the log files to get to know what
exactly happens during this imporant step.
Note that that {Ldap}{Debug}
will only switch on debug notes of
LdapContrib, not of your web server performing ldap requests on its own
depending on your setup.
Independent from LdapContrib and Foswiki itself there is a small perl utility in <wiki-install-path>/tools/ldaptools
that can be used to explore the records as returned by your LDAP server on various search requests.
This file is easy to understand and should be modified with a text editor before using it for the first
time to reflect the specific settings required to connect your LDAP server.
cd /path/to/foswiki perl tools/extension_installer <NameOfExtension> installIf you have any problems, or if the extension isn't available in
configure
, then you can still install manually from the command-line. See https://foswiki.org/Support/ManuallyInstallingExtensions for more help.
Name | Version | Description |
---|---|---|
Authen::SASL | >=2.00 | Optional |
DB_File | >=1.00 | Required |
DB_File::Lock | >=0.05 | Required |
Digest::MD5 | >=2.36 | Required |
GSSAPI | >=0.28 | Optional |
IO::Socket::INET6 | >=1.0 | Optional |
IO::Socket::SSL | >=1.0 | Optional |
Net::LDAP | >=0.33 | Required |
Text::Unidecode | >=1.27 | Required |
This work is partly sponsored by
05 Mar 2018: | replace handmade transliteration with Text::Unidecode; only force kerberos handshake when authentication is required |
25 Nov 2017: | added feature to specify multiple LDAP servers; added connection timeout |
10 Oct 2017: | fixed encoding errors of uncicode DN paths |
30 Aug 2017: | fixed checking local groups; fixed recoding values coming from the LDAP directory |
16 Jan 2017: | fixed logging in via email using an ldap-apache login manager |
11 Jan 2017: | added config parameter to switch off mapping of login names to cUIDs |
02 Sep 2016: | added ability to login using an email address |
22 Apr 2016: | added IgnoreReferrals switch; fixed occasional infinite loop when checking for an existing user; be more robust against misconfiguring ca-file and/or ca-path |
21 Sep 2015: | added LdapTemplateLogin and LdapApacheLogin managers; added RewriteLoginNames config parameter; prevent against infinite redirects when using kerberos login but no ticket may be exchanged |
08 May 2015: | added IgnorePrivateGroups flag |
16 Feb 2015: | support Active Directory's range syntax for large groups (by Jan Krueger) |
13 Feb 2015: | added support for kerberos single sign on using the KerberosLogin manager |
12 Jan 2015: | resolve name clashes even when not pre-caching |
16 Dec 2014: | fixed clash resolution (still was depending on DNs in some cases) |
24 Nov 2014: | fixed creation of cache.db on FreeBSD |
23 May 2014: | implemented feature to provide a login-to-wikiname mapping in a topic |
18 Mar 2014: | using proper locking when updating the ldap cache (Foswiki:Main/TerjeNessAndersen); rewrite of name clash resolution to use login attributes, not DNs anymore |
29 Nov 2012: | fixed decoding of ldap strings |
21 Nov 2012: | fixed ldap login manager using old api; fixed recursive traversal of distributed ldap directories; storing all blobs into a subdirectory of their own reachable by the web server |
19 Nov 2012: | fixed non-paged requests no terminating; fixed encoding of baseDN in search; fixed case comparison when excluding wiki names; added support for non-utf8 ldap directories |
11 Nov 2012: | added support for multiple subtrees searching for users and groups |
09 Nov 2012: | add support for ldap referrals and references for distributed ldap directories |
17 Oct 2012: | Item12159: added passwords_modifyable context to re-enable changing passwords from the core topics (by Sven Dowideit) |
10 Jul 2012: | improved unicode transliteration; fixed error in regular expression testing for unknown users and groups (by Jim Hague) |
26 Jun 2012: | added CaseSensitiveLogin feature, defaulting to off ; performance improvements looking up the ldap cache (by Jayen Ashar) |
11 Jan 2012: | fixed using ListIterators on undefined list values |
20 Dec 2011: | fixes deep recursion when adding AdminGroup to AdminGroup; fixed sizelimit not properly being applied to ldap query; disabled expensive debug message |
16 Dec 2010: | implemented new expand feature of GROUPINFO found in newer foswikis |
02 Dec 2010: | fixed glitch where IDs weren't extracted from the cache db |
01 Dec 2010: | added workaround to make the Foswiki::Func API usable early enough in the processing chain; fixed the way name clashes are resolved to stabilize choices once made; added refreshldap=force feature to override previous decisions resolving name clashes; deprecated WikiNameAliases in favor of RewriteWikiNames |
22 Nov 2010: | fixed removing realm from login again; improved clash report message |
16 Nov 2010: | added tool to debug ldap server connection and structure |
09 Nov 2010: | removed every lowercasing of login names; added docu and better defaults for RewriteWikiNames |
17 Sep 2010: | fixed build script; removed hardcoded normalization that stripped off domain parts from login and wiki names; fixed utf8 transcoding for modern perls; be more careful when translation of WikiNameAttributes to proper WikiNames checking existing homepages; implemented groupAllowsChange() for modern Foswikis |
17 Nov 2009: | incremental cache updates for big ldap directories and inner groups feature (Cyril Bousquet, IBM); added scope parameter searching for users and groups; added rewrite rules for wiki names; added name clash resolution for wiki names; fixed race condition in cache update leading to file corruption; cleanup of internal API to properly deal with interim caching structures |
25 May 2009: | extended transliteration of utf8 chars to polish chars (Bartosz Dziuda) |
09 Apr 2009: | added RewriteGroups and MergeGroups feature |
08 Apr 2009: | fixing nested ldap groups |
02 Mar 2009: | prevent error when called in the middle of the Foswiki constructor |
27 Feb 2009: | fixing use of uninitialized value in user mapper; optimized check for existing user to respect the exclude configuration setting; renamed LdapPassword to LdapPasswdUser again to please configure; transliteration of umlaut (this seems to happen occasionally during svn ci/co or whatever) |
11 Feb 2009: | allow utf8 chars in passwords; all strings from LDAP are tainted, even if it comes from mod_ldap via remote_user; only use LDAP query as a last resort to check if a user exists; prevent explicitly excluded login names to be added to the cache |
20 Jan 2009: | fixed getting emails for groups and login names |
19 Dec 2008: | fixed group mapping under MapGroup=off |
05 Dec 2008: | fixed group mapping |
04 Dec 2008: | fixed getting email info |
06 Oct 2008: | dropped support for TWiki < 4.2.3; added support TLS encryption (by Wolfgang Karall) |
12 Jun 2008: | added workarounds to use LDAP and MailInContrib on TWiki-4.2.0 |
25 May 2008: | added alias feature, fixed normalization error, fixed cache update issue added login manager for 4.2 |
05 May 2008: | implemented WikiNamesAliases |
14 Feb 2008: | allow to disable cache aging setting MaxCacheAge to zero |
01 Feb 2008: | distinguish groups clashing with user names by appending a suffix |
30 Jan 2008: | first beta towards TWiki-4.2 |
07 Jan 2008: | fixed initializing the cache |
21 Dec 2007: | added LdapApacheLogin, made updating the cache quasi atomic |
22 Nov 2007: | fixed recognition of WikiGroups in a mixed setting |
05 Oct 2007: | enabled native user registration using the secondary password manager; added support to change a user's LDAP password from within TWiki; added patch for TWiki.pm that backports some of the fixes from TWiki-4.2 to TWiki-4.1.2 |
05 Sep 2007: | added SASL support, added normalization of login and group names, added secondary password manager |
31 Aug 2007: | rewrite of the cache |
08 June 2007: | don't use the store object during TWiki's destructor; don't lookup login names of groups |
04 June 2007: | don't be case sensitive for login names; fixed several utf8 issues; fixed crash when no groups where found; caching mapping privately; added MaxCacheAge; added support for nested LDAP groups |
30 Apr 2007: | fixed return value on illegal lookup calls |
24 Apr 2007: | be robust against the lookup-API being called with the wrong parameters; added Debug flag; fixed/improved group loading; deprecating BasePasswd in favor of UserBase ; deprecating BaseGroup in favor of GroupBase |
04 Apr 2007: | fixed group mapping on >4.1.2; renamed BasePasswd config parameter to UserBase; renamed BaseGroup config parameter to GroupBase; working around broken configure in 4.1.x |
12 Jan 2007: | enhanced normalization of WikiNames so that they are proper WikiWords; WikiNames can be constructed from a list of LDAP attributes now |
18 Dec 2006: | various performance improvements; fixed usage of limit argument; renamed configuration option "WikiNameRemoveWhiteSpace" to "NormalizeWikiName"; support for large databases using paged LDAP search results; new configuration option "Exclude" to exclude standard TWiki user accounts, e.g. RegistrationAgent, from being looked up in LDAP; added support for faster API implementing isMemberOf ; added Config.spec file to integrate the LdapContrib into TWiki's "configure" tool; added support for WikiNames derived from mail attributes |
03 Nov 2006: | fixed binding to the server by first searching the full dn instead of assuming a fixed one (issue found by Cederic Weber); added new feature MapGroup to be able to switch off group mapping and have; login-to-wikiname conversion only |
02 Aug 2006: | added a user accounts in memory cache |
19 July 2006: | public release |
24 May 2006: | API adjustments, improved wikiname generation |
28 Apr 2006: | Initial version |
Author | Michael Daum |
Version | 8.00 |
Release | 05 Mar 2018 |
Description | |
Repository | https://github.com/foswiki/LdapContrib |
Copyright | © 2006-2018 Michael Daum http://michaeldaumconsulting.com |
License | GPL (GNU General Public License) |
Home | https://foswiki.org/Extensions/LdapContrib |
Support | https://foswiki.org/Support/LdapContrib |