Files

70 lines
1.9 KiB
Go

// Package ldaputil normalizes LDAP server addresses supplied by administrators.
package ldaputil
import (
"fmt"
"net"
"net/url"
"strings"
)
// DialURL accepts an IP address or domain name, with an optional port. Bare
// addresses use LDAPS on port 636. Existing ldap:// and ldaps:// values remain
// supported for backward compatibility.
func DialURL(address string) (string, error) {
address = strings.TrimSpace(address)
if address == "" {
return "", fmt.Errorf("LDAP 服务器地址不能为空")
}
if strings.Contains(address, "://") {
u, err := url.Parse(address)
if err != nil || (u.Scheme != "ldap" && u.Scheme != "ldaps") || u.Host == "" || u.Path != "" || u.RawQuery != "" || u.Fragment != "" {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
port := "389"
if u.Scheme == "ldaps" {
port = "636"
}
host, err := withDefaultPort(u.Host, port)
if err != nil {
return "", err
}
u.Host = host
return u.String(), nil
}
host, err := withDefaultPort(address, "636")
if err != nil {
return "", err
}
return "ldaps://" + host, nil
}
func withDefaultPort(address, defaultPort string) (string, error) {
if strings.ContainsAny(address, " \t\r\n/?#@") {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
if host, port, err := net.SplitHostPort(address); err == nil {
if host == "" || port == "" {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
return address, nil
}
host := strings.TrimSuffix(strings.TrimPrefix(address, "["), "]")
if host == "" || (strings.Contains(host, ":") && net.ParseIP(host) == nil) {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
return net.JoinHostPort(host, defaultPort), nil
}
// Hostname returns the hostname or IP for TLS ServerName selection.
func Hostname(dialURL string) string {
u, err := url.Parse(dialURL)
if err != nil {
return ""
}
return u.Hostname()
}