// Package ldap provides a LDAP authentification backend package ldap import ( "github.com/go-ldap/ldap/v3" "log" "strings" ) // Options holds package configuration type Options struct { Aliases map[string]map[string]string URI string UserDn string } // LDAP authentification backend type LDAP struct { Cfg *Options Conn *ldap.Conn } // Login tries to bind to LDAP // Returns (true, nil) if success func (a LDAP) Login(username string, password string) (bool, error) { aliasSplit := strings.SplitN(username, "__", 2) potentialUsernames := []string{username} for len(aliasSplit) == 2 { alias := aliasSplit[0] trueUsername := aliasSplit[1] // Resolve stream alias if necessary if aliases, ok := a.Cfg.Aliases[alias]; ok { if _, ok := aliases[trueUsername]; ok { log.Printf("[LDAP] Use stream alias %s for username %s", alias, trueUsername) potentialUsernames = append(potentialUsernames, trueUsername) } } } var err error = nil for _, username := range potentialUsernames { // Try to bind as user bindDn := "cn=" + username + "," + a.Cfg.UserDn err = a.Conn.Bind(bindDn, password) if err == nil { // Login succeeded if no error return true, nil } } // Unable to log in return err == nil, err } // Close LDAP connection func (a LDAP) Close() { a.Conn.Close() } // New instanciates a new LDAP connection func New(cfg *Options) (LDAP, error) { backend := LDAP{Cfg: cfg} // Connect to LDAP server c, err := ldap.DialURL(backend.Cfg.URI) backend.Conn = c return backend, err }