Commit 21a1507c by Daniel Lee Committed by Leonard Gram

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.
parent 13d9acb1
......@@ -278,18 +278,27 @@ func (a *ldapAuther) searchForUser(username string) (*LdapUserInfo, error) {
var err error
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{
BaseDN: searchBase,
Scope: ldap.ScopeWholeSubtree,
DerefAliases: ldap.NeverDerefAliases,
Attributes: []string{
a.server.Attr.Username,
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),
Attributes: attributes,
Filter: strings.Replace(a.server.SearchFilter, "%s", ldap.EscapeFilter(username), -1),
}
a.log.Debug("Ldap Search For User Request", "info", spew.Sdump(searchReq))
......
......@@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/ldap.v3"
......@@ -322,11 +323,51 @@ func TestLdapAuther(t *testing.T) {
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 {
result *ldap.SearchResult
searchCalled bool
result *ldap.SearchResult
searchCalled bool
searchAttributes []string
}
func (c *mockLdapConn) Bind(username, password string) error {
......@@ -339,8 +380,9 @@ func (c *mockLdapConn) setSearchResult(result *ldap.SearchResult) {
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.searchAttributes = sr.Attributes
return c.result, nil
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment