func Authenticate(a Authorizer, url string, user string, passwd string) error { ldap, err := openldap.Initialize(url) if err != nil { logger.Get().Error("Failed to connect the server. error: %v", err) return err } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) if a.directory.Uid != "" { err = ldap.Bind(fmt.Sprintf("%s=%s,%s", a.directory.Uid, user, a.directory.Base), passwd) if err != nil { logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err) return err } } else { if ldap.Bind(fmt.Sprintf("uid=%s,%s", user, a.directory.Base), passwd) != nil { err = ldap.Bind(fmt.Sprintf("cn=%s,%s", user, a.directory.Base), passwd) if err != nil { logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err) return err } } } return nil }
/* * * openldap example program : * * - 1 : * * - specify URL for LDAP connexion with user and passwd * - ldap and ldaps is supported, * - anonymous connexion is done with an empty user string * - base (DN) is needed for many LDAP server (it depends on LDAP data design) * * - 2 : * * - you can set some LDAP options. * - authentification with Bind() * * - 3 : setup LDAP query search. * - 4 : print search results. * */ func main() { var user, passwd, url, base string // (1) - connexion options url = "ldap://some.host:389/" // url = "ldaps://some.host:636/" user = "******" passwd = "..." base = "" ldap, err := openldap.Initialize(url) if err != nil { fmt.Printf("LDAP::Initialize() : connexion error\n") return } // (2.1) - options ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) // (2.2) - authentification (Bind) err = ldap.Bind(user, passwd) if err != nil { fmt.Printf("LDAP::Bind() : bind error\n") fmt.Println(err) return } defer ldap.Close() // (3) : search method // -------------------------------------- Ldap::SearchAll() -------------------------------------- scope := openldap.LDAP_SCOPE_SUBTREE // LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE filter := "cn=*admin*" attributes := []string{"cn", "sn", "givenname", "mail"} // leave empty for all attributes // SearchAll(base string, scope int, filter string, attributes []string) (*LdapSearchResult, error) result, err := ldap.SearchAll(base, scope, filter, attributes) if err != nil { fmt.Println(err) return } // (4) - print LdapSearchResult(s) fmt.Printf("# num results : %d\n", result.Count()) fmt.Printf("# search : %s\n", result.Filter()) fmt.Printf("# base : %s\n", result.Base()) fmt.Printf("# attributes : [%s]\n", strings.Join(result.Attributes(), ", ")) for _, entry := range result.Entries() { fmt.Printf("dn=%s\n", entry.Dn()) for _, attr := range entry.Attributes() { fmt.Printf("%s=[%s]\n", attr.Name(), strings.Join(attr.Values(), ", ")) } fmt.Printf("\n") } }
func initLdap() { url = "ldap://ldap.domain.com:1389/" base_dn = "ou=People,dc=dc,dc=com" ldap, err = openldap.Initialize(url) if err != nil { fmt.Printf("LDAP::Initialize() : connexion error\n") return } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) }
/* uses: https://github.com/mqu/openldap * * openldap example program : * * - 1 : * * - specify URL for LDAP connexion with user and passwd * - ldap and ldaps is supported, * - anonymous connexion is done with an empty user string * - base (DN) is needed for many LDAP server (it depends on LDAP data design) * * - 2 : * * - you can set some LDAP options. * - authentification with Bind() * * - 3 : setup LDAP query search. * - 4 : print search results. * */ func main() { var user, passwd, url string // (1) - connexion options url = "ldap://*****:*****@gmial.com"} m["password"] = []string{"Changepwd1"} ldap.Add("cn=pankaj,ou=people,o=sevenSeas", m) fmt.Println("Successfully added an entry") }
// Connect and Bind to LDAP server using self.opts func (self *LdapSearchApp) Connect() error { var err error self.ldap, err = openldap.Initialize(self.opts.host) if err != nil { return err } //FIXME: should be an external option self.ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) err = self.ldap.Bind(self.opts.user, self.opts.passwd) if err != nil { return err } return nil }
func lookupLdap(username, password string) bool { ldap_server, _ := globalCfg.ReadString("ldap_server", "") dn_fmt, _ := globalCfg.ReadString("dn_fmt", "") ldap, err := openldap.Initialize(ldap_server) if err != nil { log.Error(err) return false } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) dn := fmt.Sprintf(dn_fmt, username) err = ldap.Bind(dn, password) if err != nil { log.Warning(err) return false } ldap.Close() return true }
func Authenticate(directory models.Directory, url string, user string, passwd string) error { if len(directory.Base) == 0 || len(passwd) == 0 { logger.Get().Error("Failed to find any LDAP configuration") return mkerror("Failed to find any LDAP configuration") } ldap, err := openldap.Initialize(url) if err != nil { logger.Get().Error("Failed to connect the server. error: %v", err) return err } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) err = ldap.Bind(fmt.Sprintf("%s=%s,%s", directory.Uid, user, directory.Base), passwd) if err != nil { logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err) return err } return nil }
func connectOpenldap(host string, port string, dn string, passwd string) (*openldap.Ldap, error) { //init url := "ldap://" + host + ":" + port + "/" ldap, err := openldap.Initialize(url) if err != nil { log.Printf("Cannot connect to openldap.Reason:%v", err) return nil, err } log.Printf("Connected") //setup ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) //connect err = ldap.Bind(dn, passwd) if err != nil { log.Printf("Cannot bind to openldap.Reason:%v", err) return nil, err } log.Printf("Binded") return ldap, err }
// Authenticate checks user's credential agains LDAP based on basedn template and LDAP URL, // if the check is successful a dummy record will be insert into DB, such that this user can // be associated to other entities in the system. func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) { ldapURL := os.Getenv("LDAP_URL") if ldapURL == "" { return nil, errors.New("Can not get any available LDAP_URL.") } log.Debug("ldapURL:", ldapURL) p := m.Principal for _, c := range metaChars { if strings.ContainsRune(p, c) { return nil, fmt.Errorf("the principal contains meta char: %q", c) } } ldap, err := openldap.Initialize(ldapURL) if err != nil { return nil, err } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) ldapBaseDn := os.Getenv("LDAP_BASE_DN") if ldapBaseDn == "" { return nil, errors.New("Can not get any available LDAP_BASE_DN.") } baseDn := fmt.Sprintf(ldapBaseDn, m.Principal) log.Debug("baseDn:", baseDn) err = ldap.Bind(baseDn, m.Password) if err != nil { return nil, err } defer ldap.Close() scope := openldap.LDAP_SCOPE_SUBTREE // LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE filter := "objectClass=*" attributes := []string{"mail"} result, err := ldap.SearchAll(baseDn, scope, filter, attributes) if err != nil { return nil, err } u := models.User{} if len(result.Entries()) == 1 { en := result.Entries()[0] for _, attr := range en.Attributes() { val := attr.Values()[0] if attr.Name() == "mail" { u.Email = val } } } u.Username = m.Principal log.Debug("username:"******",email:", u.Email) exist, err := dao.UserExists(u, "username") if err != nil { return nil, err } if exist { currentUser, err := dao.GetUser(u) if err != nil { return nil, err } u.UserID = currentUser.UserID } else { u.Realname = m.Principal u.Password = "******" u.Comment = "registered from LDAP." userID, err := dao.Register(u) if err != nil { return nil, err } u.UserID = int(userID) } return &u, nil }
// Authenticate checks user's credential against LDAP based on basedn template and LDAP URL, // if the check is successful a dummy record will be inserted into DB, such that this user can // be associated to other entities in the system. func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) { p := m.Principal for _, c := range metaChars { if strings.ContainsRune(p, c) { return nil, fmt.Errorf("the principal contains meta char: %q", c) } } ldapURL := config.LDAP().URL if ldapURL == "" { return nil, errors.New("can not get any available LDAP_URL") } log.Debug("ldapURL:", ldapURL) ldap, err := openldap.Initialize(ldapURL) if err != nil { return nil, err } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) ldapBaseDn := config.LDAP().BaseDn if ldapBaseDn == "" { return nil, errors.New("can not get any available LDAP_BASE_DN") } log.Debug("baseDn:", ldapBaseDn) ldapSearchDn := config.LDAP().SearchDn if ldapSearchDn != "" { log.Debug("Search DN: ", ldapSearchDn) ldapSearchPwd := config.LDAP().SearchPwd err = ldap.Bind(ldapSearchDn, ldapSearchPwd) if err != nil { log.Debug("Bind search dn error", err) return nil, err } } attrName := config.LDAP().UID filter := config.LDAP().Filter if filter != "" { filter = "(&" + filter + "(" + attrName + "=" + m.Principal + "))" } else { filter = "(" + attrName + "=" + m.Principal + ")" } log.Debug("one or more filter", filter) ldapScope := config.LDAP().Scope var scope int if ldapScope == "1" { scope = openldap.LDAP_SCOPE_BASE } else if ldapScope == "2" { scope = openldap.LDAP_SCOPE_ONELEVEL } else { scope = openldap.LDAP_SCOPE_SUBTREE } attributes := []string{"uid", "cn", "mail", "email"} result, err := ldap.SearchAll(ldapBaseDn, scope, filter, attributes) if err != nil { return nil, err } if len(result.Entries()) == 0 { log.Warningf("Not found an entry.") return nil, nil } else if len(result.Entries()) != 1 { log.Warningf("Found more than one entry.") return nil, nil } en := result.Entries()[0] bindDN := en.Dn() log.Debug("found entry:", en) err = ldap.Bind(bindDN, m.Password) if err != nil { log.Debug("Bind user error", err) return nil, err } defer ldap.Close() u := models.User{} for _, attr := range en.Attributes() { val := attr.Values()[0] switch attr.Name() { case "uid": u.Realname = val case "cn": u.Realname = val case "mail": u.Email = val case "email": u.Email = val } } u.Username = m.Principal log.Debug("username:"******",email:", u.Email) exist, err := dao.UserExists(u, "username") if err != nil { return nil, err } if exist { currentUser, err := dao.GetUser(u) if err != nil { return nil, err } u.UserID = currentUser.UserID } else { u.Realname = m.Principal u.Password = "******" u.Comment = "registered from LDAP." if u.Email == "" { u.Email = u.Username + "@placeholder.com" } userID, err := dao.Register(u) if err != nil { return nil, err } u.UserID = int(userID) } return &u, nil }
// List the LDAP users func (a Authorizer) ListExternalUsers() (users []models.User, err error) { url := GetUrl(a.directory.Address, a.directory.Port) Uid := "Uid" DisplayName := "DisplayName" FullName := "CN" if a.directory.Uid != "" { Uid = a.directory.Uid } if a.directory.DisplayName != "" { DisplayName = a.directory.DisplayName } if a.directory.FullName != "" { FullName = a.directory.FullName } ldap, err := openldap.Initialize(url) if err != nil { logger.Get().Error("failed to connect the LDAP/AD server. error: %v", err) return nil, err } if a.directory.DomainAdmin != "" { err = ldap.Bind(fmt.Sprintf("%s=%s,%s", Uid, a.directory.DomainAdmin, a.directory.Base), a.directory.Password) if err != nil { logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err) return nil, err } } scope := openldap.LDAP_SCOPE_SUBTREE filter := "(objectclass=*)" attributes := []string{Uid, DisplayName, FullName, "Mail"} rv, err := ldap.SearchAll(a.directory.Base, scope, filter, attributes) if err != nil { logger.Get().Error("Failed to search LDAP/AD server. error: %v", err) return nil, err } for _, entry := range rv.Entries() { user := models.User{} fullName := "" for _, attr := range entry.Attributes() { switch attr.Name() { case Uid: user.Username = strings.Join(attr.Values(), ", ") case "Mail": user.Email = strings.Join(attr.Values(), ", ") case DisplayName: user.FirstName = strings.Join(attr.Values(), ", ") case FullName: fullName = strings.Join(attr.Values(), ", ") } if len(fullName) != 0 && len(user.FirstName) != 0 { lastName := strings.Split(fullName, user.FirstName) if len(lastName) > 1 { user.LastName = strings.TrimSpace(lastName[1]) } } } // Assiging the default roles user.Role = a.defaultRole user.Groups = append(user.Groups, a.defaultGroup) user.Type = authprovider.External if len(user.Username) != 0 { users = append(users, user) } } return users, nil }
// List the LDAP users func (a Authorizer) ListExternalUsers(search string, page, count int) (externalUsers models.ExternalUsers, err error) { directory, err := a.GetDirectory() if err != nil { return externalUsers, err } url := GetUrl(directory.LdapServer, directory.Port) DisplayName := "DisplayName" FirstName := "CN" LastName := "SN" Email := "mail" if directory.DisplayName != "" { DisplayName = directory.DisplayName } if directory.FirstName != "" { FirstName = directory.FirstName } if directory.LastName != "" { LastName = directory.LastName } if directory.Email != "" { Email = directory.Email } ldap, err := openldap.Initialize(url) if err != nil { logger.Get().Error("failed to connect the LDAP/AD server. error: %v", err) return externalUsers, err } if directory.DomainAdmin != "" { block, err := aes.NewCipher([]byte(CipherKey)) if err != nil { logger.Get().Error("failed to generate new cipher") return externalUsers, nil } ciphertext := []byte(directory.Password) iv := ciphertext[:aes.BlockSize] stream := cipher.NewOFB(block, iv) hkey := make([]byte, 100) stream = cipher.NewOFB(block, iv) stream.XORKeyStream(hkey, ciphertext[aes.BlockSize:]) err = ldap.Bind(fmt.Sprintf("%s=%s,%s", directory.Uid, directory.DomainAdmin, directory.Base), string(hkey)) if err != nil { logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err) return externalUsers, err } } scope := openldap.LDAP_SCOPE_SUBTREE // If the search string is empty, it will list all the users // If the search string contains 'mail=tjey*' it will returns the list of all // users start with 'tjey' // If the search string contains 'tim' this will return list of all users // names contains the word 'tim' // Possible search strings 'mail=t*redhat.com' / 'tim*' / '*john*' / '*peter' filter := "(objectclass=*)" if len(search) > 0 { if strings.Contains(search, "=") { filter = fmt.Sprintf("(%s*)", search) } else if strings.Contains(search, "*") { filter = fmt.Sprintf("(%s=%s)", directory.Uid, search) } else { filter = fmt.Sprintf("(%s=*%s*)", directory.Uid, search) } } attributes := []string{directory.Uid, DisplayName, FirstName, LastName, Email} rv, err := ldap.SearchAll(directory.Base, scope, filter, attributes) if err != nil { logger.Get().Error("Failed to search LDAP/AD server. error: %v", err) return externalUsers, err } from := (page-1)*count + 1 to := from + count - 1 i := 0 for _, entry := range rv.Entries() { i++ if i < from { continue } if i > to { break } user := models.User{} for _, attr := range entry.Attributes() { switch attr.Name() { case directory.Uid: user.Username = strings.Join(attr.Values(), ", ") case Email: user.Email = strings.Join(attr.Values(), ", ") // Some setup may have an attribute like mail or email // or operator can't be used between strings to combind cases case "email": user.Email = strings.Join(attr.Values(), ", ") case FirstName: user.FirstName = strings.Join(attr.Values(), ", ") case LastName: user.LastName = strings.Join(attr.Values(), ", ") } } // Assiging the default roles user.Role = a.defaultRole user.Groups = append(user.Groups, a.defaultGroup) user.Type = authprovider.External if len(user.Username) != 0 { externalUsers.Users = append(externalUsers.Users, user) } } externalUsers.TotalCount = rv.Count() externalUsers.StartIndex = from externalUsers.EndIndex = to if externalUsers.EndIndex > externalUsers.TotalCount { externalUsers.EndIndex = externalUsers.TotalCount } return externalUsers, nil }