mirror of
https://github.com/grafana/grafana.git
synced 2026-08-13 06:34:55 -05:00
fix allow anonymous initial bind for ldap search
This commit is contained in:
+12
-1
@@ -18,6 +18,7 @@ import (
|
|||||||
|
|
||||||
type ILdapConn interface {
|
type ILdapConn interface {
|
||||||
Bind(username, password string) error
|
Bind(username, password string) error
|
||||||
|
UnauthenticatedBind(username string) error
|
||||||
Search(*ldap.SearchRequest) (*ldap.SearchResult, error)
|
Search(*ldap.SearchRequest) (*ldap.SearchResult, error)
|
||||||
StartTLS(*tls.Config) error
|
StartTLS(*tls.Config) error
|
||||||
Close()
|
Close()
|
||||||
@@ -259,7 +260,17 @@ func (a *ldapAuther) initialBind(username, userPassword string) error {
|
|||||||
bindPath = fmt.Sprintf(a.server.BindDN, username)
|
bindPath = fmt.Sprintf(a.server.BindDN, username)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.conn.Bind(bindPath, userPassword); err != nil {
|
bindFn := func() error {
|
||||||
|
return a.conn.Bind(bindPath, userPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
if userPassword == "" {
|
||||||
|
bindFn = func() error {
|
||||||
|
return a.conn.UnauthenticatedBind(bindPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bindFn(); err != nil {
|
||||||
a.log.Info("Initial bind failed", "error", err)
|
a.log.Info("Initial bind failed", "error", err)
|
||||||
|
|
||||||
if ldapErr, ok := err.(*ldap.Error); ok {
|
if ldapErr, ok := err.(*ldap.Error); ok {
|
||||||
|
|||||||
+81
-3
@@ -13,6 +13,70 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestLdapAuther(t *testing.T) {
|
func TestLdapAuther(t *testing.T) {
|
||||||
|
Convey("initialBind", t, func() {
|
||||||
|
Convey("Given bind dn and password configured", func() {
|
||||||
|
conn := &mockLdapConn{}
|
||||||
|
var actualUsername, actualPassword string
|
||||||
|
conn.bindProvider = func(username, password string) error {
|
||||||
|
actualUsername = username
|
||||||
|
actualPassword = password
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ldapAuther := &ldapAuther{
|
||||||
|
conn: conn,
|
||||||
|
server: &LdapServerConf{
|
||||||
|
BindDN: "cn=%s,o=users,dc=grafana,dc=org",
|
||||||
|
BindPassword: "bindpwd",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := ldapAuther.initialBind("user", "pwd")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(ldapAuther.requireSecondBind, ShouldBeTrue)
|
||||||
|
So(actualUsername, ShouldEqual, "cn=user,o=users,dc=grafana,dc=org")
|
||||||
|
So(actualPassword, ShouldEqual, "bindpwd")
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Given bind dn configured", func() {
|
||||||
|
conn := &mockLdapConn{}
|
||||||
|
var actualUsername, actualPassword string
|
||||||
|
conn.bindProvider = func(username, password string) error {
|
||||||
|
actualUsername = username
|
||||||
|
actualPassword = password
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ldapAuther := &ldapAuther{
|
||||||
|
conn: conn,
|
||||||
|
server: &LdapServerConf{
|
||||||
|
BindDN: "cn=%s,o=users,dc=grafana,dc=org",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := ldapAuther.initialBind("user", "pwd")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(ldapAuther.requireSecondBind, ShouldBeFalse)
|
||||||
|
So(actualUsername, ShouldEqual, "cn=user,o=users,dc=grafana,dc=org")
|
||||||
|
So(actualPassword, ShouldEqual, "pwd")
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Given empty bind dn and password", func() {
|
||||||
|
conn := &mockLdapConn{}
|
||||||
|
unauthenticatedBindWasCalled := false
|
||||||
|
var actualUsername string
|
||||||
|
conn.unauthenticatedBindProvider = func(username string) error {
|
||||||
|
unauthenticatedBindWasCalled = true
|
||||||
|
actualUsername = username
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ldapAuther := &ldapAuther{
|
||||||
|
conn: conn,
|
||||||
|
server: &LdapServerConf{},
|
||||||
|
}
|
||||||
|
err := ldapAuther.initialBind("user", "pwd")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(ldapAuther.requireSecondBind, ShouldBeTrue)
|
||||||
|
So(unauthenticatedBindWasCalled, ShouldBeTrue)
|
||||||
|
So(actualUsername, ShouldBeEmpty)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Convey("When translating ldap user to grafana user", t, func() {
|
Convey("When translating ldap user to grafana user", t, func() {
|
||||||
|
|
||||||
@@ -365,12 +429,26 @@ func TestLdapAuther(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mockLdapConn struct {
|
type mockLdapConn struct {
|
||||||
result *ldap.SearchResult
|
result *ldap.SearchResult
|
||||||
searchCalled bool
|
searchCalled bool
|
||||||
searchAttributes []string
|
searchAttributes []string
|
||||||
|
bindProvider func(username, password string) error
|
||||||
|
unauthenticatedBindProvider func(username string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *mockLdapConn) Bind(username, password string) error {
|
func (c *mockLdapConn) Bind(username, password string) error {
|
||||||
|
if c.bindProvider != nil {
|
||||||
|
return c.bindProvider(username, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *mockLdapConn) UnauthenticatedBind(username string) error {
|
||||||
|
if c.unauthenticatedBindProvider != nil {
|
||||||
|
return c.unauthenticatedBindProvider(username)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user