func (h ldapHandler) ping() error { healthy := false for k, s := range h.servers { var l *ldap.Conn var err error dest := fmt.Sprintf("%s:%d", s.Hostname, s.Port) start := time.Now() if h.servers[0].Scheme == "ldaps" { tlsCfg := &tls.Config{} if h.cfg.Backend.Insecure { tlsCfg.InsecureSkipVerify = true } l, err = ldap.DialTLS("tcp", dest, tlsCfg) } else if h.servers[0].Scheme == "ldap" { l, err = ldap.Dial("tcp", dest) } elapsed := time.Since(start) h.lock.Lock() if err != nil || l == nil { log.Error(fmt.Sprintf("Server %s:%d ping failed: %s", s.Hostname, s.Port, err.Error())) h.servers[k].Ping = 0 h.servers[k].Status = Down } else { healthy = true h.servers[k].Ping = elapsed h.servers[k].Status = Up l.Close() // prank caller } h.lock.Unlock() } log.Debug("Server health: %# v", pretty.Formatter(h.servers)) b, err := json.Marshal(h.servers) if err != nil { log.Error(fmt.Sprintf("Error encoding tail data: %s", err.Error())) } stats_backend.Set("servers", stringer(string(b))) if healthy == false { return fmt.Errorf("No healthy servers") } return nil }
func (o *opts) doquery(q query) (*ldap.SearchResult, error) { sr := &ldap.SearchResult{} // parse the ldap URL u, err := url.Parse(q.ldapURL) if err != nil { return sr, err } var port int if u.Scheme == "ldaps" { port = 636 } else if u.Scheme == "ldap" { port = 389 } else { return sr, fmt.Errorf("Unknown LDAP scheme: %s", u.Scheme) } parts := strings.Split(u.Host, ":") hostname := parts[0] if len(parts) > 1 { port, err = strconv.Atoi(parts[1]) if err != nil { return sr, err } } // connect to the ldap server var l *ldap.Conn if u.Scheme == "ldaps" { tlsConfig := tls.Config{} if o.goklp_insecure_skip_verify { tlsConfig.InsecureSkipVerify = true } l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", hostname, port), &tlsConfig) if err != nil { return sr, err } } else if u.Scheme == "ldap" { l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", hostname, port)) if err != nil { return sr, err } } defer l.Close() // do an ldap bind err = l.Bind(q.user, q.passwd) if err != nil { return sr, err } // do the ldap search search := ldap.NewSearchRequest( q.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, q.filter, q.Attributes, nil) sr, err = l.Search(search) if err != nil { return sr, err } return sr, nil }
func pingLdap(url *url.URL, dial func(proto, addr string) (*ldap.Conn, error)) (err error) { var proto, addr string proto, addr, err = utilUrl.Socket(url.Host) if err != nil { return e.Forward(err) } var conn *ldap.Conn conn, err = dial(proto, addr) if err != nil { return e.Forward(err) } defer func() { conn.Close() }() pass, ok := url.User.Password() if !ok { err = e.New("no password") return } if len(url.Path) > 0 { url.Path = url.Path[1:] } dn := "cn=" + url.User.Username() + "," + url.Path err = conn.Bind(dn, pass) if err != nil { err = e.Forward(err) return } attrs := map[string]bool{ "cn": true, "uid": true, "uidNumber": true, "gidNumber": true, } attrsStr := make([]string, 0, len(attrs)) for val := range attrs { attrsStr = append(attrsStr, val) } search := &ldap.SearchRequest{ BaseDN: basedn(dn), Scope: ldap.ScopeWholeSubtree, DerefAliases: ldap.DerefAlways, Filter: "(&(objectclass=*)(cn=" + url.User.Username() + "))", Attributes: attrsStr, } sr, err := conn.Search(search) if err != nil { err = e.Forward(err) return } if len(sr.Entries) == 1 { entry := sr.Entries[0] if entry.DN == dn { count := 0 for _, attr := range entry.Attributes { if _, found := attrs[attr.Name]; found { count++ } else { return e.New("ldap search returned a no requested attribute") } } if count != len(attrs) { return e.New("wrong number of attributes, required %v, got %v", len(attrs), count) } } } return nil }