mirror of
https://github.com/project-zot/zot.git
synced 2025-01-27 23:01:43 -05:00
ldap: improve recovery when connection failures
This commit is contained in:
parent
0550752e63
commit
5447ec5bdd
2 changed files with 38 additions and 13 deletions
|
@ -19,5 +19,6 @@ var (
|
||||||
ErrBadUser = errors.New("ldap: non-existent user")
|
ErrBadUser = errors.New("ldap: non-existent user")
|
||||||
ErrEntriesExceeded = errors.New("ldap: too many entries returned")
|
ErrEntriesExceeded = errors.New("ldap: too many entries returned")
|
||||||
ErrLDAPEmptyPassphrase = errors.New("ldap: empty passphrase")
|
ErrLDAPEmptyPassphrase = errors.New("ldap: empty passphrase")
|
||||||
|
ErrLDAPBadConn = errors.New("ldap: bad connection")
|
||||||
ErrLDAPConfig = errors.New("config: invalid LDAP configuration")
|
ErrLDAPConfig = errors.New("config: invalid LDAP configuration")
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/anuvu/zot/errors"
|
"github.com/anuvu/zot/errors"
|
||||||
"github.com/jtblin/go-ldap-client"
|
"github.com/jtblin/go-ldap-client"
|
||||||
|
@ -11,6 +12,8 @@ import (
|
||||||
goldap "gopkg.in/ldap.v2"
|
goldap "gopkg.in/ldap.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxRetries = 8
|
||||||
|
|
||||||
type LDAPClient struct {
|
type LDAPClient struct {
|
||||||
ldap.LDAPClient
|
ldap.LDAPClient
|
||||||
subtreeSearch bool
|
subtreeSearch bool
|
||||||
|
@ -69,6 +72,17 @@ func (lc *LDAPClient) Connect() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sleepAndRetry(retries, maxRetries int) bool {
|
||||||
|
if retries > maxRetries {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if retries < maxRetries {
|
||||||
|
time.Sleep(time.Duration(retries) * time.Second) // gradually backoff
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Authenticate authenticates the user against the ldap backend.
|
// Authenticate authenticates the user against the ldap backend.
|
||||||
func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]string, error) {
|
func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]string, error) {
|
||||||
if password == "" {
|
if password == "" {
|
||||||
|
@ -76,21 +90,31 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
||||||
return false, nil, errors.ErrLDAPEmptyPassphrase
|
return false, nil, errors.ErrLDAPEmptyPassphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
err := lc.Connect()
|
connected := false
|
||||||
if err != nil {
|
for retries := 0; !connected && sleepAndRetry(retries, maxRetries); retries++ {
|
||||||
return false, nil, err
|
err := lc.Connect()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// First bind with a read only user
|
||||||
|
if lc.BindDN != "" && lc.BindPassword != "" {
|
||||||
|
err := lc.Conn.Bind(lc.BindDN, lc.BindPassword)
|
||||||
|
if err != nil {
|
||||||
|
lc.log.Error().Err(err).Str("bindDN", lc.BindDN).Msg("bind failed")
|
||||||
|
// clean up the cached conn, so we can retry
|
||||||
|
lc.Conn.Close()
|
||||||
|
lc.Conn = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// First bind with a read only user
|
// exhausted all retries?
|
||||||
if lc.BindDN != "" && lc.BindPassword != "" {
|
if !connected {
|
||||||
err := lc.Conn.Bind(lc.BindDN, lc.BindPassword)
|
lc.log.Error().Err(errors.ErrLDAPBadConn).Msg("exhausted all retries")
|
||||||
if err != nil {
|
return false, nil, errors.ErrLDAPBadConn
|
||||||
lc.log.Error().Err(err).Str("bindDN", lc.BindDN).Msg("bind failed")
|
|
||||||
// clean up the cached conn, so we can retry
|
|
||||||
lc.Conn.Close()
|
|
||||||
lc.Conn = nil
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes := append(lc.Attributes, "dn")
|
attributes := append(lc.Attributes, "dn")
|
||||||
|
|
Loading…
Add table
Reference in a new issue