From 5cd51e3251b1fd71f7b9e476337a7b50cabb815f Mon Sep 17 00:00:00 2001 From: Rob61 <51970653+Rob61@users.noreply.github.com> Date: Thu, 13 Aug 2020 10:26:59 +0200 Subject: [PATCH] Fix go-gitea#6898 Added support for multiple LDAP(S) servers in auth source. Servers are separated by space characters. --- modules/auth/ldap/ldap.go | 59 ++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 66676f2829d5..10bc6310a762 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -118,29 +118,56 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { } func dial(ls *Source) (*ldap.Conn, error) { + log.Trace("Dialing LDAP with security protocol (%v) without verifying: %v", ls.SecurityProtocol, ls.SkipVerify) + // Tokenize the host string + hostList := strings.Split(ls.Host, " ") - tlsCfg := &tls.Config{ - ServerName: ls.Host, - InsecureSkipVerify: ls.SkipVerify, - } - if ls.SecurityProtocol == SecurityProtocolLDAPS { - return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), tlsCfg) - } + var err error + // For each host in the list + for _, host := range hostList { - conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port)) - if err != nil { - return nil, fmt.Errorf("Dial: %v", err) - } + tlsCfg := &tls.Config{ + ServerName: host, + InsecureSkipVerify: ls.SkipVerify, + } + + // LDAPS + if ls.SecurityProtocol == SecurityProtocolLDAPS { - if ls.SecurityProtocol == SecurityProtocolStartTLS { - if err = conn.StartTLS(tlsCfg); err != nil { - conn.Close() - return nil, fmt.Errorf("StartTLS: %v", err) + conn, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", host, ls.Port), tlsCfg) + if err != nil { + // Connection failed. Lets try again with the next host. + log.Trace("Dial with LDAPS: %v", err) + continue + } + + // Successful + return conn, err + } + + // LDAP + conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", host, ls.Port)) + if err != nil { + // Connection failed. Lets try again with the next host. + log.Trace("Dial with LDAP: %v", err) + continue + } + + // LDAP with TLS + if ls.SecurityProtocol == SecurityProtocolStartTLS { + + if err = conn.StartTLS(tlsCfg); err != nil { + conn.Close() + // Connection failed. Lets try again with the next host. + log.Trace("Dial with LDAP and TLS: %v", err) + continue + } } } - return conn, nil + // Failed. All Servers were unreachable + return nil, fmt.Errorf("Dial failed: %v. Tried for servers: %v", err, hostList) } func bindUser(l *ldap.Conn, userDN, passwd string) error {