diff --git a/lib/api/api_auth.go b/lib/api/api_auth.go index 9a623e93a..415cf7b43 100644 --- a/lib/api/api_auth.go +++ b/lib/api/api_auth.go @@ -166,6 +166,35 @@ func authLDAP(username string, password string, cfg config.LDAPConfiguration) bo return false } + if cfg.SearchFilter == "" && cfg.SearchBaseDN == "" { + // We're done here. + return true + } + + if cfg.SearchFilter == "" || cfg.SearchBaseDN == "" { + l.Warnln("LDAP configuration: both searchFilter and searchBaseDN must be set, or neither.") + return false + } + + // If a search filter and search base is set we do an LDAP search for + // the user. If this matches precisely one user then we are good to go. + // The search filter uses the same %s interpolation as the bind DN. + + searchString := fmt.Sprintf(cfg.SearchFilter, username) + const sizeLimit = 2 // we search for up to two users -- we only want to match one, so getting any number >1 is a failure. + const timeLimit = 60 // Search for up to a minute... + searchReq := ldap.NewSearchRequest(cfg.SearchBaseDN, ldap.ScopeWholeSubtree, ldap.DerefFindingBaseObj, sizeLimit, timeLimit, false, searchString, nil, nil) + + res, err := connection.Search(searchReq) + if err != nil { + l.Warnln("LDAP Search:", err) + return false + } + if len(res.Entries) != 1 { + l.Infof("Wrong number of LDAP search results, %d != 1", len(res.Entries)) + return false + } + return true } diff --git a/lib/config/ldapconfiguration.go b/lib/config/ldapconfiguration.go index c233e66bf..9a3fca7e4 100644 --- a/lib/config/ldapconfiguration.go +++ b/lib/config/ldapconfiguration.go @@ -11,6 +11,8 @@ type LDAPConfiguration struct { BindDN string `xml:"bindDN,omitempty" json:"bindDN"` Transport LDAPTransport `xml:"transport,omitempty" json:"transport"` InsecureSkipVerify bool `xml:"insecureSkipVerify,omitempty" json:"insecureSkipVerify" default:"false"` + SearchBaseDN string `xml:"searchBaseDN,omitempty" json:"searchBaseDN"` + SearchFilter string `xml:"searchFilter,omitempty" json:"searchFilter"` } func (c LDAPConfiguration) Copy() LDAPConfiguration {