Skip to content

Commit

Permalink
Add support for connecting to multiple LDAP hosts by iterating over s…
Browse files Browse the repository at this point in the history
…pace-separated host strings

This update enhances the LDAP client by allowing it to connect to multiple LDAP servers. The 'Host' field now accepts a space-separated string of LDAP host addresses. The `Connect` method iterates over these hosts, attempting to establish a connection with each one until a successful connection is made.

Key changes:
- Split the 'Host' field into individual host addresses.
- Iterated over each host to attempt a connection.
- Implemented error handling to try the next host if a connection fails.
- Updated the connection logic to support both non-SSL and SSL connections, including handling TLS upgrades.

This change improves the robustness of the LDAP client by ensuring that the application can failover to another LDAP server if the primary server is unavailable.
  • Loading branch information
Nausherwan Khan authored and Nausherwan Khan committed Aug 30, 2024
1 parent 9e5c7b8 commit f2ee4a5
Showing 1 changed file with 42 additions and 25 deletions.
67 changes: 42 additions & 25 deletions utils/ldap/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,39 +82,56 @@ type LDAPClient struct {
// Connect connects to the ldap backend.
func (lc *LDAPClient) Connect() error {
if lc.Conn == nil {
// Split the space-separated host string into a slice of hosts
hosts := strings.Split(lc.Host, " ")

var l *ldap.Conn
var err error
address := fmt.Sprintf("%s:%d", lc.Host, lc.Port)
if !lc.UseSSL {
l, err = ldap.Dial("tcp", address)
if err != nil {
return err
}

// Reconnect with TLS
if !lc.SkipTLS {
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})


// Iterate over each host and attempt to connect
for _, host := range hosts {
address := fmt.Sprintf("%s:%d", host, lc.Port)
if !lc.UseSSL {
l, err = ldap.Dial("tcp", address)
if err != nil {
return err
continue // Try the next host
}

// Reconnect with TLS
if !lc.SkipTLS {
err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})

Check failure

Code scanning / CodeQL

Disabled TLS certificate check High

InsecureSkipVerify should not be used in production code.
if err != nil {
l.Close() // Close the connection before trying the next host
continue // Try the next host
}
}
} else {
config := &tls.Config{
InsecureSkipVerify: lc.InsecureSkipVerify,
ServerName: lc.ServerName,
}
if lc.ClientCertificates != nil && len(lc.ClientCertificates) > 0 {
config.Certificates = lc.ClientCertificates
}
l, err = ldap.DialTLS("tcp", address, config)
if err != nil {
continue // Try the next host
}
}
} else {
config := &tls.Config{
InsecureSkipVerify: lc.InsecureSkipVerify,
ServerName: lc.ServerName,
}
if lc.ClientCertificates != nil && len(lc.ClientCertificates) > 0 {
config.Certificates = lc.ClientCertificates
}
l, err = ldap.DialTLS("tcp", address, config)
if err != nil {
return err
}

lc.Conn = l
return nil // Successfully connected to a host
}

lc.Conn = l
// If no connection was successful, return the last error encountered
if err != nil {
return err
}
return errors.New("failed to connect to any LDAP server")
}
return nil

return nil // Already connected
}

// Close closes the ldap backend connection.
Expand Down

0 comments on commit f2ee4a5

Please sign in to comment.