You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.7 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright github.com/juju2013. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. // package ldap provide functions & structure to query a LDAP ldap directory
  5. // For now, it's mainly tested again an MS Active Directory service, see README.md for more information
  6. package ldap
  7. import (
  8. "fmt"
  9. "github.com/gogits/gogs/modules/log"
  10. goldap "github.com/juju2013/goldap"
  11. )
  12. // Basic LDAP authentication service
  13. type Ldapsource struct {
  14. Name string // canonical name (ie. corporate.ad)
  15. Host string // LDAP host
  16. Port int // port number
  17. BaseDN string // Base DN
  18. Attributes string // Attribut to search
  19. Filter string // Query filter to validate entry
  20. MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
  21. Enabled bool // if this source is disabled
  22. }
  23. //Global LDAP directory pool
  24. var (
  25. Authensource []Ldapsource
  26. )
  27. // Add a new source (LDAP directory) to the global pool
  28. func AddSource(name string, host string, port int, basedn string, attributes string, filter string, msadsaformat string) {
  29. ldaphost := Ldapsource{name, host, port, basedn, attributes, filter, msadsaformat, true}
  30. Authensource = append(Authensource, ldaphost)
  31. }
  32. //LoginUser : try to login an user to LDAP sources, return requested (attribut,true) if ok, ("",false) other wise
  33. //First match wins
  34. //Returns first attribute if exists
  35. func LoginUser(name, passwd string) (a string, r bool) {
  36. r = false
  37. for _, ls := range Authensource {
  38. a, r = ls.searchEntry(name, passwd)
  39. if r {
  40. return
  41. }
  42. }
  43. return
  44. }
  45. // searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
  46. func (ls Ldapsource) searchEntry(name, passwd string) (string, bool) {
  47. l, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
  48. if err != nil {
  49. log.Debug("LDAP Connect error, disabled source %s", ls.Host)
  50. ls.Enabled = false
  51. return "", false
  52. }
  53. defer l.Close()
  54. nx := fmt.Sprintf(ls.MsAdSAFormat, name)
  55. err = l.Bind(nx, passwd)
  56. if err != nil {
  57. log.Debug("LDAP Authan failed for %s, reason: %s", nx, err.Error())
  58. return "", false
  59. }
  60. search := goldap.NewSearchRequest(
  61. ls.BaseDN,
  62. goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
  63. fmt.Sprintf(ls.Filter, name),
  64. []string{ls.Attributes},
  65. nil)
  66. sr, err := l.Search(search)
  67. if err != nil {
  68. log.Debug("LDAP Authen OK but not in filter %s", name)
  69. return "", false
  70. }
  71. log.Debug("LDAP Authen OK: %s", name)
  72. if len(sr.Entries) > 0 {
  73. r := sr.Entries[0].GetAttributeValue(ls.Attributes)
  74. return r, true
  75. }
  76. return "", true
  77. }