mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ldap: fixes #14432. Fix for IPA v4.6.4
IPA v4.6.4 introduced a fix that does not allow empty attributes to be sent in a search request. This fix only adds attributes to the request if they are mapped in the ldap toml file.
This commit is contained in:
parent
13d9acb1ef
commit
21a1507c77
@ -278,18 +278,27 @@ func (a *ldapAuther) searchForUser(username string) (*LdapUserInfo, error) {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
for _, searchBase := range a.server.SearchBaseDNs {
|
for _, searchBase := range a.server.SearchBaseDNs {
|
||||||
|
attributes := make([]string, 0)
|
||||||
|
|
||||||
|
appendIfNotEmpty := func(slice []string, attr string) []string {
|
||||||
|
if attr == "" {
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
return append(slice, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes = appendIfNotEmpty(attributes, a.server.Attr.Username)
|
||||||
|
attributes = appendIfNotEmpty(attributes, a.server.Attr.Surname)
|
||||||
|
attributes = appendIfNotEmpty(attributes, a.server.Attr.Email)
|
||||||
|
attributes = appendIfNotEmpty(attributes, a.server.Attr.Name)
|
||||||
|
attributes = appendIfNotEmpty(attributes, a.server.Attr.MemberOf)
|
||||||
|
|
||||||
searchReq := ldap.SearchRequest{
|
searchReq := ldap.SearchRequest{
|
||||||
BaseDN: searchBase,
|
BaseDN: searchBase,
|
||||||
Scope: ldap.ScopeWholeSubtree,
|
Scope: ldap.ScopeWholeSubtree,
|
||||||
DerefAliases: ldap.NeverDerefAliases,
|
DerefAliases: ldap.NeverDerefAliases,
|
||||||
Attributes: []string{
|
Attributes: attributes,
|
||||||
a.server.Attr.Username,
|
Filter: strings.Replace(a.server.SearchFilter, "%s", ldap.EscapeFilter(username), -1),
|
||||||
a.server.Attr.Surname,
|
|
||||||
a.server.Attr.Email,
|
|
||||||
a.server.Attr.Name,
|
|
||||||
a.server.Attr.MemberOf,
|
|
||||||
},
|
|
||||||
Filter: strings.Replace(a.server.SearchFilter, "%s", ldap.EscapeFilter(username), -1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a.log.Debug("Ldap Search For User Request", "info", spew.Sdump(searchReq))
|
a.log.Debug("Ldap Search For User Request", "info", spew.Sdump(searchReq))
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"gopkg.in/ldap.v3"
|
"gopkg.in/ldap.v3"
|
||||||
@ -322,11 +323,51 @@ func TestLdapAuther(t *testing.T) {
|
|||||||
So(sc.addOrgUserCmd.Role, ShouldEqual, "Admin")
|
So(sc.addOrgUserCmd.Role, ShouldEqual, "Admin")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("When searching for a user and not all five attributes are mapped", t, func() {
|
||||||
|
mockLdapConnection := &mockLdapConn{}
|
||||||
|
entry := ldap.Entry{
|
||||||
|
DN: "dn", Attributes: []*ldap.EntryAttribute{
|
||||||
|
{Name: "username", Values: []string{"roelgerrits"}},
|
||||||
|
{Name: "surname", Values: []string{"Gerrits"}},
|
||||||
|
{Name: "email", Values: []string{"roel@test.com"}},
|
||||||
|
{Name: "name", Values: []string{"Roel"}},
|
||||||
|
{Name: "memberof", Values: []string{"admins"}},
|
||||||
|
}}
|
||||||
|
result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}}
|
||||||
|
mockLdapConnection.setSearchResult(&result)
|
||||||
|
|
||||||
|
// Set up attribute map without surname and email
|
||||||
|
ldapAuther := &ldapAuther{
|
||||||
|
server: &LdapServerConf{
|
||||||
|
Attr: LdapAttributeMap{
|
||||||
|
Username: "username",
|
||||||
|
Name: "name",
|
||||||
|
MemberOf: "memberof",
|
||||||
|
},
|
||||||
|
SearchBaseDNs: []string{"BaseDNHere"},
|
||||||
|
},
|
||||||
|
conn: mockLdapConnection,
|
||||||
|
log: log.New("test-logger"),
|
||||||
|
}
|
||||||
|
|
||||||
|
searchResult, err := ldapAuther.searchForUser("roelgerrits")
|
||||||
|
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(searchResult, ShouldNotBeNil)
|
||||||
|
|
||||||
|
// User should be searched in ldap
|
||||||
|
So(mockLdapConnection.searchCalled, ShouldBeTrue)
|
||||||
|
|
||||||
|
// No empty attributes should be added to the search request
|
||||||
|
So(len(mockLdapConnection.searchAttributes), ShouldEqual, 3)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockLdapConn struct {
|
type mockLdapConn struct {
|
||||||
result *ldap.SearchResult
|
result *ldap.SearchResult
|
||||||
searchCalled bool
|
searchCalled bool
|
||||||
|
searchAttributes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *mockLdapConn) Bind(username, password string) error {
|
func (c *mockLdapConn) Bind(username, password string) error {
|
||||||
@ -339,8 +380,9 @@ func (c *mockLdapConn) setSearchResult(result *ldap.SearchResult) {
|
|||||||
c.result = result
|
c.result = result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *mockLdapConn) Search(*ldap.SearchRequest) (*ldap.SearchResult, error) {
|
func (c *mockLdapConn) Search(sr *ldap.SearchRequest) (*ldap.SearchResult, error) {
|
||||||
c.searchCalled = true
|
c.searchCalled = true
|
||||||
|
c.searchAttributes = sr.Attributes
|
||||||
return c.result, nil
|
return c.result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user