|
|
|
@ -35,24 +35,24 @@ const ATTR_MODIFYTIMESTAMP = "modifytimestamp" |
|
|
|
|
|
|
|
|
|
type ConfigFile struct { |
|
|
|
|
Suffix string `json:"suffix"` |
|
|
|
|
BindAddress string `json:"bind_address"` |
|
|
|
|
Bind string `json:"bind"` |
|
|
|
|
BindSecure string `json:"bind_secure"` |
|
|
|
|
ConsulHost string `json:"consul_host"` |
|
|
|
|
Acl []string `json:"acl"` |
|
|
|
|
TLSCertFile string `json:"tls_cert_file"` |
|
|
|
|
TLSKeyFile string `json:"tls_key_file"` |
|
|
|
|
TLSServerName string `json:"tls_server_name"` |
|
|
|
|
UseStartTLS bool `json:"use_starttls"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type Config struct { |
|
|
|
|
Suffix string |
|
|
|
|
BindAddress string |
|
|
|
|
ConsulHost string |
|
|
|
|
Suffix string |
|
|
|
|
Bind string |
|
|
|
|
BindSecure string |
|
|
|
|
ConsulHost string |
|
|
|
|
|
|
|
|
|
Acl ACL |
|
|
|
|
|
|
|
|
|
TLSConfig *tls.Config |
|
|
|
|
UseStartTLS bool |
|
|
|
|
TLSConfig *tls.Config |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type Server struct { |
|
|
|
@ -71,7 +71,8 @@ var configFlag = flag.String("config", "./config.json", "Configuration file path |
|
|
|
|
|
|
|
|
|
func readConfig() Config { |
|
|
|
|
config_file := ConfigFile{ |
|
|
|
|
BindAddress: "0.0.0.0:389", |
|
|
|
|
Bind: "0.0.0.0:389", |
|
|
|
|
BindSecure: "0.0.0.0:636", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bytes, err := ioutil.ReadFile(*configFlag) |
|
|
|
@ -90,11 +91,11 @@ func readConfig() Config { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret := Config{ |
|
|
|
|
Suffix: config_file.Suffix, |
|
|
|
|
BindAddress: config_file.BindAddress, |
|
|
|
|
ConsulHost: config_file.ConsulHost, |
|
|
|
|
Acl: acl, |
|
|
|
|
UseStartTLS: config_file.UseStartTLS, |
|
|
|
|
Suffix: config_file.Suffix, |
|
|
|
|
Bind: config_file.Bind, |
|
|
|
|
BindSecure: config_file.BindSecure, |
|
|
|
|
ConsulHost: config_file.ConsulHost, |
|
|
|
|
Acl: acl, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if config_file.TLSCertFile != "" && config_file.TLSKeyFile != "" && config_file.TLSServerName != "" { |
|
|
|
@ -116,8 +117,6 @@ func readConfig() Config { |
|
|
|
|
Certificates: []tls.Certificate{cert}, |
|
|
|
|
ServerName: config_file.TLSServerName, |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
log.Printf("Warning: no TLS configuration provided, running an insecure server.") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ret |
|
|
|
@ -152,17 +151,7 @@ func main() { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Create a new LDAP Server
|
|
|
|
|
ldapserver := ldap.NewServer() |
|
|
|
|
ldapserver.NewUserState = func() ldap.UserState { |
|
|
|
|
return &State{ |
|
|
|
|
login: Login{ |
|
|
|
|
user: "ANONYMOUS", |
|
|
|
|
groups: []string{}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create routes
|
|
|
|
|
routes := ldap.NewRouteMux() |
|
|
|
|
|
|
|
|
|
routes.Bind(gobottin.handleBind) |
|
|
|
@ -172,33 +161,72 @@ func main() { |
|
|
|
|
routes.Delete(gobottin.handleDelete) |
|
|
|
|
routes.Modify(gobottin.handleModify) |
|
|
|
|
|
|
|
|
|
if config.TLSConfig != nil && config.UseStartTLS { |
|
|
|
|
if config.TLSConfig != nil { |
|
|
|
|
routes.Extended(gobottin.handleStartTLS). |
|
|
|
|
RequestName(ldap.NoticeOfStartTLS).Label("StartTLS") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ldapserver.Handle(routes) |
|
|
|
|
// Create LDAP servers
|
|
|
|
|
var ldapServer, ldapServerSecure *ldap.Server = nil, nil |
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
// When CTRL+C, SIGINT and SIGTERM signal occurs
|
|
|
|
|
// Then stop server gracefully
|
|
|
|
|
ch := make(chan os.Signal) |
|
|
|
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) |
|
|
|
|
<-ch |
|
|
|
|
close(ch) |
|
|
|
|
ldapserver.Stop() |
|
|
|
|
}() |
|
|
|
|
// Bind on standard LDAP port without TLS
|
|
|
|
|
if config.Bind != "" { |
|
|
|
|
ldapServer = ldap.NewServer() |
|
|
|
|
ldapServer.Handle(routes) |
|
|
|
|
ldapServer.NewUserState = gobottin.newUserState |
|
|
|
|
go func() { |
|
|
|
|
err := ldapServer.ListenAndServe(config.Bind) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if config.TLSConfig != nil && !config.UseStartTLS { |
|
|
|
|
secureConn := func(s *ldap.Server) { |
|
|
|
|
s.Listener = tls.NewListener(s.Listener, config.TLSConfig) |
|
|
|
|
// Bind on LDAP secure port with TLS
|
|
|
|
|
if config.BindSecure != "" { |
|
|
|
|
if config.TLSConfig != nil { |
|
|
|
|
ldapServerSecure := ldap.NewServer() |
|
|
|
|
ldapServerSecure.Handle(routes) |
|
|
|
|
ldapServerSecure.NewUserState = gobottin.newUserState |
|
|
|
|
secureConn := func(s *ldap.Server) { |
|
|
|
|
s.Listener = tls.NewListener(s.Listener, config.TLSConfig) |
|
|
|
|
} |
|
|
|
|
go func() { |
|
|
|
|
err := ldapServerSecure.ListenAndServe(config.BindSecure, secureConn) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} else { |
|
|
|
|
fmt.Printf("Warning: no valid TLS configuration was provided, not binding on %s", config.BindSecure) |
|
|
|
|
} |
|
|
|
|
err = ldapserver.ListenAndServe(config.BindAddress, secureConn) |
|
|
|
|
} else { |
|
|
|
|
err = ldapserver.ListenAndServe(config.BindAddress) |
|
|
|
|
} |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
|
|
|
|
|
if ldapServer == nil && ldapServerSecure == nil { |
|
|
|
|
panic("Not doing anything.") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// When CTRL+C, SIGINT and SIGTERM signal occurs
|
|
|
|
|
// Then stop server gracefully
|
|
|
|
|
ch := make(chan os.Signal) |
|
|
|
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) |
|
|
|
|
<-ch |
|
|
|
|
close(ch) |
|
|
|
|
|
|
|
|
|
if ldapServer != nil { |
|
|
|
|
ldapServer.Stop() |
|
|
|
|
} |
|
|
|
|
if ldapServerSecure != nil { |
|
|
|
|
ldapServerSecure.Stop() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (server *Server) newUserState() ldap.UserState { |
|
|
|
|
return &State{ |
|
|
|
|
login: Login{ |
|
|
|
|
user: "ANONYMOUS", |
|
|
|
|
groups: []string{}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|