package main import ( "crypto/tls" "errors" "fmt" "github.com/go-ldap/ldap/v3" ) type LDAPAuth struct { Addr string Port int IsTLS bool Base string BindUsername string BindPassword string } func (l LDAPAuth) checkAuth(username, password string) (res bool, err error) { tlsCnf := tls.Config{InsecureSkipVerify: true} var c *ldap.Conn if l.IsTLS { c, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", l.Addr, l.Port), &tlsCnf) if err != nil { return false, err } } else { c, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", l.Addr, l.Port)) if err != nil { return false, err } // Reconnect with TLS err = c.StartTLS(&tlsCnf) if err != nil { return false, err } } defer c.Close() if l.BindUsername != "" { err = c.Bind(l.BindUsername, l.BindPassword) if err != nil { return false, err } } // Search for the given username searchRequest := ldap.NewSearchRequest( l.Base, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, fmt.Sprintf("(&(objectClass=person)(uid=%s))", username), []string{"dn"}, nil, ) sr, err := c.Search(searchRequest) if err != nil { return false, err } if len(sr.Entries) != 1 { return false, errors.New("User does not exist or too many entries returned") } userdn := sr.Entries[0].DN err = c.Bind(userdn, password) if err != nil { return false, err } return true, nil }