diff --git a/.gitignore b/.gitignore index 3430434..9360a59 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,9 @@ *.gz *.swp -LdapContrib.md5 -LdapContrib.sha1 -LdapContrib.tgz -LdapContrib.txt -LdapContrib.zip -LdapContrib_installer -LdapContrib_installer.pl +/LdapContrib.md5 +/LdapContrib.sha1 +/LdapContrib.tgz +/LdapContrib.txt +/LdapContrib.zip +/LdapContrib_installer +/LdapContrib_installer.pl diff --git a/data/System/LdapContrib.txt b/data/System/LdapContrib.txt index 5c31d71..82f400b 100644 --- a/data/System/LdapContrib.txt +++ b/data/System/LdapContrib.txt @@ -500,6 +500,7 @@ This work was partly sponsored by ---++ Change History %TABLE{columnwidths="7em" tablewidth="100%"}% +| 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 | diff --git a/lib/Foswiki/Contrib/LdapContrib.pm b/lib/Foswiki/Contrib/LdapContrib.pm index 9d13050..f0c2716 100644 --- a/lib/Foswiki/Contrib/LdapContrib.pm +++ b/lib/Foswiki/Contrib/LdapContrib.pm @@ -30,8 +30,8 @@ use Encode (); use Foswiki::Func (); use Foswiki::Plugins (); -our $VERSION = '7.40'; -our $RELEASE = '22 Apr 2016'; +our $VERSION = '7.50'; +our $RELEASE = '02 Sep 2016'; our $SHORTDESCRIPTION = 'LDAP services for Foswiki'; our $NO_PREFS_IN_TOPIC = 1; our %sharedLdapContrib; diff --git a/lib/Foswiki/Contrib/LdapContrib/Config.spec b/lib/Foswiki/Contrib/LdapContrib/Config.spec index 7fcbbbd..9950146 100644 --- a/lib/Foswiki/Contrib/LdapContrib/Config.spec +++ b/lib/Foswiki/Contrib/LdapContrib/Config.spec @@ -1,4 +1,4 @@ -# ---+ Extensions +# ---+ Security and Authentication # ---++ LDAP # This is the configuration used by the LdapContrib and the # LdapNgPlugin. @@ -42,7 +42,7 @@ $Foswiki::cfg{Ldap}{Base} = 'dc=my,dc=domain,dc=com'; # be to maintain the directory in a consistent state and remove stale referrals not to harm queries performance. $Foswiki::cfg{Ldap}{IgnoreReferrals} = 0; -# **STRING** +# **STRING CHECK="undefok emptyok" ** # The DN to use when binding to the LDAP server; if undefined anonymous binding # will be used. Example 'cn=proxyuser,dc=my,dc=domain,dc=com' $Foswiki::cfg{Ldap}{BindDN} = ''; @@ -83,29 +83,29 @@ $Foswiki::cfg{Ldap}{SASLMechanism} = 'PLAIN CRAM-MD5 EXTERNAL ANONYMOUS'; # You will need to specify the servers CA File using the TLSCAFile or TLSCAPath option $Foswiki::cfg{Ldap}{UseTLS} = 0; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok" ** # This defines the version of the SSL/TLS protocol to use. Possible values are: # 'sslv2', 'sslv3', 'sslv2/3' or 'tlsv1' $Foswiki::cfg{Ldap}{TLSSSLVersion} = 'tlsv1'; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok"** # Specify how to verify the servers certificate. Possible values are: 'require', 'optional' # or 'require'. $Foswiki::cfg{Ldap}{TLSVerify} = 'require'; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok"** # Filename containing the certificate of the CA which signed the server’s certificate. $Foswiki::cfg{Ldap}{TLSCAFile} = ''; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok"** # Pathname of the directory containing CA certificates. $Foswiki::cfg{Ldap}{TLSCAPath} = ''; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok"** # Client side certificate file $Foswiki::cfg{Ldap}{TLSClientCert} = ''; -# **STRING** +# **STRING DISPLAY_IF="{Ldap}{UseTLS}" CHECK="undefok emptyok"** # Client side private key file $Foswiki::cfg{Ldap}{TLSClientKey} = ''; @@ -127,7 +127,7 @@ $Foswiki::cfg{Ldap}{UserBase} = ['ou=people,dc=my,dc=domain,dc=com']; # Filter to be used to find login accounts. Compare to GroupFilter below $Foswiki::cfg{Ldap}{LoginFilter} = 'objectClass=posixAccount'; -# **SELECT sub,one** +# **SELECT sub,one CHECK="undefok emptyok"** # The scope of the search for users starting at UserBase. While "sub" search recursively # a "one" will only search up to one level under the UserBase. $Foswiki::cfg{Ldap}{UserScope} = 'sub'; @@ -162,7 +162,7 @@ $Foswiki::cfg{Ldap}{NormalizeLoginNames} = 0; # Enable/disable case sensitive login names. If disabled case doesn't matter logging in. $Foswiki::cfg{Ldap}{CaseSensitiveLogin} = 0; -# **STRING** +# **STRING CHECK="undefok emptyok"** # Alias old !WikiNames to new account. This is a comma separated list of # "OldName=NewName" values. # Warning: this setting is deprecated - use RewriteWikiNames instead @@ -225,7 +225,7 @@ $Foswiki::cfg{Ldap}{GroupBase} = ['ou=group,dc=my,dc=domain,dc=com']; # Filter to be used to find groups. Compare to LoginFilter. $Foswiki::cfg{Ldap}{GroupFilter} = 'objectClass=posixGroup'; -# **SELECT sub,one** +# **SELECT sub,one CHECK="undefok emptyok"** # The scope of the search for groups starting at GroupBase. While "sub" search recursively # a "one" will only search up to one level under the GroupBase. $Foswiki::cfg{Ldap}{GroupScope} = 'sub'; diff --git a/lib/Foswiki/Contrib/LdapContrib/MANIFEST b/lib/Foswiki/Contrib/LdapContrib/MANIFEST index d7c32bf..946ad8e 100644 --- a/lib/Foswiki/Contrib/LdapContrib/MANIFEST +++ b/lib/Foswiki/Contrib/LdapContrib/MANIFEST @@ -8,3 +8,4 @@ lib/Foswiki/LoginManager/LdapTemplateLogin.pm 0644 lib/Foswiki/Users/LdapPasswdUser.pm 0644 lib/Foswiki/Users/LdapUserMapping.pm 0644 tools/ldaptest 0755 +tools/ldaptest.conf.example 0755 diff --git a/lib/Foswiki/Contrib/LdapContrib/build.pl b/lib/Foswiki/Contrib/LdapContrib/build.pl index 2396be3..8bf5277 100755 --- a/lib/Foswiki/Contrib/LdapContrib/build.pl +++ b/lib/Foswiki/Contrib/LdapContrib/build.pl @@ -1,7 +1,4 @@ -#!/usr/bin/perl -w -# -# Build for NatSkin -# +#!/usr/bin/env perl BEGIN { foreach my $pc (split(/:/, $ENV{FOSWIKI_LIBS})) { unshift @INC, $pc; diff --git a/lib/Foswiki/LoginManager/LdapApacheLogin.pm b/lib/Foswiki/LoginManager/LdapApacheLogin.pm index 11f5470..25f63a0 100644 --- a/lib/Foswiki/LoginManager/LdapApacheLogin.pm +++ b/lib/Foswiki/LoginManager/LdapApacheLogin.pm @@ -66,7 +66,11 @@ sub loadSession { my $authUser = $this->SUPER::loadSession(@_); $authUser = Foswiki::Sandbox::untaintUnchecked($authUser); - return $this->{ldap}->loadSession($authUser); + if ($this->{ldap}->getWikiNameOfLogin($authUser)) { + $authUser = $this->{ldap}->loadSession($authUser); + } + + return $authUser; } 1; diff --git a/lib/Foswiki/LoginManager/LdapTemplateLogin.pm b/lib/Foswiki/LoginManager/LdapTemplateLogin.pm index f07d027..9421ca9 100644 --- a/lib/Foswiki/LoginManager/LdapTemplateLogin.pm +++ b/lib/Foswiki/LoginManager/LdapTemplateLogin.pm @@ -66,7 +66,18 @@ sub loadSession { my $authUser = $this->SUPER::loadSession(@_); $authUser = Foswiki::Sandbox::untaintUnchecked($authUser); - return $this->{ldap}->loadSession($authUser); + if ($this->{ldap}->getWikiNameOfLogin($authUser)) { + $authUser = $this->{ldap}->loadSession($authUser); + } else { + # try email + my $logins = $this->{ldap}->getLoginOfEmail($authUser); + if (defined $logins && scalar(@$logins)) { + $authUser = $logins->[0]; + $authUser = $this->{ldap}->loadSession(shift @$logins); + } + } + + return $authUser; } 1; diff --git a/lib/Foswiki/Users/LdapPasswdUser.pm b/lib/Foswiki/Users/LdapPasswdUser.pm index 3706dd0..c5bf07f 100644 --- a/lib/Foswiki/Users/LdapPasswdUser.pm +++ b/lib/Foswiki/Users/LdapPasswdUser.pm @@ -158,7 +158,8 @@ sub userExists { return 1 if $this->{ldap}->getWikiNameOfLogin($name) - || $this->{ldap}->getLoginOfWikiName($name); + || $this->{ldap}->getLoginOfWikiName($name) + || $this->{ldap}->getLoginOfEmail($name); if ($this->{secondaryPasswordManager}) { #writeDebug("asking secondary password manager"); @@ -188,6 +189,18 @@ sub checkPassword { # get user record my $dn = $this->{ldap}->getDnOfLogin($login); + + # try to login using an email + unless ($dn) { + my $email = $login; + my $logins = $this->{ldap}->getLoginOfEmail($email); + if (defined $logins) { + foreach my $l (@$logins) { + $dn = $this->{ldap}->getDnOfLogin($l); + last if $dn; + } + } + } writeDebug("dn not found") unless $dn; return $this->{ldap}->connect($dn, $passU) diff --git a/lib/Foswiki/Users/LdapUserMapping.pm b/lib/Foswiki/Users/LdapUserMapping.pm index 9bcd315..de13eba 100644 --- a/lib/Foswiki/Users/LdapUserMapping.pm +++ b/lib/Foswiki/Users/LdapUserMapping.pm @@ -495,8 +495,9 @@ sub findUserByWikiName { if ($this->isGroup($wikiName)) { push @users, $wikiName; } else { - my $loginName = $this->{ldap}->getLoginOfWikiName($wikiName) || $wikiName; + my $loginName = $this->{ldap}->getLoginOfWikiName($wikiName); return $this->SUPER::findUserByWikiName($wikiName) if !$loginName && $this->{ldap}->{secondaryPasswordManager}; + $loginName ||= $wikiName; my $cUID = $this->login2cUID($loginName, 1); push @users, $cUID if $cUID; } diff --git a/tools/ldaptest b/tools/ldaptest index 68c2542..319777c 100755 --- a/tools/ldaptest +++ b/tools/ldaptest @@ -24,31 +24,18 @@ use Net::LDAP qw(LDAP_REFERRAL); use Authen::SASL (); use URI::ldap; -# usage: ldaptet 'ldap-query' - -## PLEASE MODIFIY ############################################# - -# server name or IP address -my $server = 'localhost'; - -# dn from where searches are performed recursively -my $baseDN = 'dc=nodomain'; - -# username and credentials used to connect to the LDAP server; -# if unset an anonymous connect will be used -# CAUTION: when typing in a password, this is plain text. -# please make sure that this file is only readable for authorized personell -my $bindUser = ''; -my $bindPassword = ''; - -my $useSASL = 0; -my $saslMechanism = 'GSSAPI'; - -# maximum number of records returned -my $sizeLimit = 10; - -# possible values: "never", "search", "find", "always" -my $deref = "always"; +our $server; +our $baseDN = 'dc=nodomain'; +our $bindUser = ''; +our $bindPassword = ''; +our $useSASL = 0; +our $saslMechanism = 'GSSAPI'; +our $sizeLimit = 10; +our $deref = "always"; + +require "ldaptest.conf"; + +die "no server specified. please configure ldaptest.conf" unless $server; ############################################################### ldapSearch($server, $baseDN, $ARGV[0] || '(objectClass=*)'); diff --git a/tools/ldaptest.conf.example b/tools/ldaptest.conf.example new file mode 100644 index 0000000..a6cf7ef --- /dev/null +++ b/tools/ldaptest.conf.example @@ -0,0 +1,24 @@ +# configuration file for ldaptest + +# server name or IP address +$server = ''; + +# dn from where searches are performed recursively +$baseDN = ''; + +# username and credentials used to connect to the LDAP server; +# if unset an anonymous connect will be used +# CAUTION: when typing in a password, this is plain text. +# please make sure that this file is only readable for authorized personell +$bindUser = ''; +$bindPassword = ''; + +# security settings +$useSASL = 0; +$saslMechanism = 'GSSAPI'; + +# maximum number of records returned +$sizeLimit = 10; + +# possible values: "never", "search", "find", "always" +$deref = "always";