Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}