From 67fa504e20095d9acd5537b46f604ce8baa4e44a Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 19 Jan 2020 13:00:53 +0100 Subject: Add ldapserver source in here & add support for client state --- main.go | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index baf0e09..1fc5d3b 100644 --- a/main.go +++ b/main.go @@ -1,18 +1,18 @@ package main import ( + "encoding/base64" + "encoding/json" "fmt" "log" + "math/rand" "os" "os/signal" - "syscall" "strings" - "encoding/json" - "encoding/base64" - "math/rand" + "syscall" + ldap "./ldapserver" consul "github.com/hashicorp/consul/api" - ldap "github.com/vjeantet/ldapserver" message "github.com/vjeantet/goldap/message" ) @@ -28,7 +28,7 @@ func dnToConsul(dn string) string { } type DNComponent struct { - Type string + Type string Value string } @@ -43,7 +43,7 @@ func parseDN(dn string) ([]DNComponent, error) { return nil, fmt.Errorf("Wrong DN component: %s (expected type=value)", rdn) } ret = append(ret, DNComponent{ - Type: splits[0], + Type: splits[0], Value: splits[1], }) } @@ -56,7 +56,11 @@ type Config struct { type Server struct { config Config - kv *consul.KV + kv *consul.KV +} + +type State struct { + bindDn string } type Attributes map[string]interface{} @@ -73,7 +77,7 @@ func main() { kv := client.KV() // TODO read config from somewhere - config := Config { + config := Config{ Suffix: "dc=gobottin,dc=eu", } @@ -85,6 +89,9 @@ func main() { //Create a new LDAP Server ldapserver := ldap.NewServer() + ldapserver.NewUserState = func() ldap.UserState { + return &State{} + } routes := ldap.NewRouteMux() routes.Bind(gobottin.handleBind) @@ -104,7 +111,7 @@ func main() { } func (server *Server) init() error { - pair, _, err := server.kv.Get(dnToConsul(server.config.Suffix) + "/attribute=objectClass", nil) + pair, _, err := server.kv.Get(dnToConsul(server.config.Suffix)+"/attribute=objectClass", nil) if err != nil { return err } @@ -114,7 +121,7 @@ func (server *Server) init() error { } base_attributes := Attributes{ - "objectClass": []string{"top", "dcObject", "organization"}, + "objectClass": []string{"top", "dcObject", "organization"}, "structuralObjectClass": "Organization", } suffix_dn, err := parseDN(server.config.Suffix) @@ -135,12 +142,12 @@ func (server *Server) init() error { admin_dn := "cn=admin," + server.config.Suffix admin_attributes := Attributes{ - "objectClass": []string{"simpleSecurityObject", "organizationalRole"}, - "description": "LDAP administrator", - "cn": "admin", - "userpassword": admin_pass_hash, + "objectClass": []string{"simpleSecurityObject", "organizationalRole"}, + "description": "LDAP administrator", + "cn": "admin", + "userpassword": admin_pass_hash, "structuralObjectClass": "organizationalRole", - "permissions": []string{"read", "write"}, + "permissions": []string{"read", "write"}, } err = server.addElements(admin_dn, admin_attributes) @@ -173,10 +180,11 @@ func (server *Server) addElements(dn string, attrs Attributes) error { return nil } -func (server *Server) handleBind(w ldap.ResponseWriter, m *ldap.Message) { +func (server *Server) handleBind(s ldap.UserState, w ldap.ResponseWriter, m *ldap.Message) { + state := s.(*State) r := m.GetBindRequest() - result_code, err := server.handleBindInternal(w, r) + result_code, err := server.handleBindInternal(state, w, r) res := ldap.NewBindResponse(result_code) if err != nil { @@ -186,9 +194,9 @@ func (server *Server) handleBind(w ldap.ResponseWriter, m *ldap.Message) { w.Write(res) } -func (server *Server) handleBindInternal(w ldap.ResponseWriter, r message.BindRequest) (int, error) { +func (server *Server) handleBindInternal(state *State, w ldap.ResponseWriter, r message.BindRequest) (int, error) { - pair, _, err := server.kv.Get(dnToConsul(string(r.Name())) + "/attribute=userpassword", nil) + pair, _, err := server.kv.Get(dnToConsul(string(r.Name()))+"/attribute=userpassword", nil) if err != nil { return ldap.LDAPResultOperationsError, err } @@ -205,6 +213,7 @@ func (server *Server) handleBindInternal(w ldap.ResponseWriter, r message.BindRe valid := SSHAMatches(hash, []byte(r.AuthenticationSimple())) if valid { + state.bindDn = string(r.Name()) return ldap.LDAPResultSuccess, nil } else { return ldap.LDAPResultInvalidCredentials, nil -- cgit v1.2.3