From 8e4537d2ef7cad3428d1ca668568d928f2a472d3 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 26 Jan 2020 21:03:18 +0100 Subject: Fixes --- .gitignore | 1 + README.md | 2 +- config.json | 13 ------------- config.json.example | 13 +++++++++++++ main.go | 15 ++++++++++++--- util.go | 14 +++++++------- 6 files changed, 34 insertions(+), 24 deletions(-) delete mode 100644 config.json create mode 100644 config.json.example diff --git a/.gitignore b/.gitignore index b5e5c05..b4ba0a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ gobottin +config.json diff --git a/README.md b/README.md index a18e052..e8b2487 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ A rule is a string composed of five fields separated by `:`. The fields are the 1. The name of the user that must be bound (logged in) for the rule to apply. May contain wildcards such as `*` (see the format used by Go's `path.Match`). The special name `ANONYMOUS` applies to clients before they bind to an LDAP entity. 2. The groups that the user must be a part of, separated by spaces. Wildcards may also be used. If several groups (or wildcard group patterns) are specified, for each pattern the user must be part of a group that matches it. -3. The action, a subset of `read`, `add`, `delete`, `modify` separated by spaces. +3. The action, a subset of `bind`, `read`, `add`, `delete`, `modify` separated by spaces. 4. The target entity of the action as a pattern that may contain wildcards. The special word `SELF` is replaced by the entity name of the bound user before trying to match. 5. The allowed attributes for a read, add or modify operation. This is specified as a list of patterns to include and exclude attributes, separated by spaces. A pattern that starts by `!` is an exclude pattern, otherwise it is an include pattern. To read/write an attribute, it has to match at least one include pattern and not match any exclude pattern. Delete operations do not check for any attribute, thus as soon as `delete` is included in the allowed actions, the right to delete entities is granted. diff --git a/config.json b/config.json deleted file mode 100644 index f4c2781..0000000 --- a/config.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "suffix": "dc=gobottin,dc=eu", - "bind_address": "127.0.0.1:10389", - "acl": [ - "ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:", - "ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:", - "*,dc=gobottin,dc=eu::read:*:* !userpassword", - "*::read modify:SELF:*", - "cn=admin,dc=gobottin,dc=eu::read add modify delete:*:*", - "*:cn=admin,ou=groups,dc=gobottin,dc=eu:read add modify delete:*:*" - ] -} - diff --git a/config.json.example b/config.json.example new file mode 100644 index 0000000..f4c2781 --- /dev/null +++ b/config.json.example @@ -0,0 +1,13 @@ +{ + "suffix": "dc=gobottin,dc=eu", + "bind_address": "127.0.0.1:10389", + "acl": [ + "ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:", + "ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:", + "*,dc=gobottin,dc=eu::read:*:* !userpassword", + "*::read modify:SELF:*", + "cn=admin,dc=gobottin,dc=eu::read add modify delete:*:*", + "*:cn=admin,ou=groups,dc=gobottin,dc=eu:read add modify delete:*:*" + ] +} + diff --git a/main.go b/main.go index 26d46b3..d55601b 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main -// @FIXME: Panics if invalid keys are in consul (consulToDN in util.go) +// @FIXME: Auto populate entryuuid creatorsname createtimestamp modifiersname modifytimestamp (uuid: github.com/google/uuid, timestamps: 20060102150405Z) +// @FIXME: Use memberof and not memberOf // @FIXME: Implement missing search filters (in applyFilter) // @FIXME: Add an initial prefix to the consul key value @@ -112,6 +113,8 @@ func readConfig() Config { } func main() { + flag.Parse() + ldap.Logger = log.New(os.Stdout, "[ldapserver] ", log.LstdFlags) config := readConfig() @@ -739,7 +742,10 @@ func (server *Server) handleDeleteInternal(state *State, r *message.DelRequest) return ldap.LDAPResultNoSuchObject, fmt.Errorf("Not found: %s", dn) } for _, item := range items { - itemDN, _ := consulToDN(item.Key) + itemDN, _, err := consulToDN(item.Key) + if err != nil { + continue + } if itemDN != dn { return ldap.LDAPResultNotAllowedOnNonLeaf, fmt.Errorf( "Cannot delete %d as it has children", dn) @@ -833,7 +839,10 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques prevEntry := Entry{} for _, item := range items { - itemDN, attr := consulToDN(item.Key) + itemDN, attr, err := consulToDN(item.Key) + if err != nil { + continue + } if itemDN != dn { panic("itemDN != dn in handleModifyInternal") } diff --git a/util.go b/util.go index d8ae58e..014805c 100644 --- a/util.go +++ b/util.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "log" "strings" consul "github.com/hashicorp/consul/api" @@ -24,7 +23,7 @@ func dnToConsul(dn string) (string, error) { return strings.Join(rdns, "/"), nil } -func consulToDN(key string) (string, string) { +func consulToDN(key string) (string, string, error) { path := strings.Split(key, "/") dn := "" for _, cpath := range path { @@ -33,16 +32,14 @@ func consulToDN(key string) (string, string) { } kv := strings.Split(cpath, "=") if len(kv) == 2 && kv[0] == "attribute" { - return dn, kv[1] + return dn, kv[1], nil } if dn != "" { dn = "," + dn } dn = cpath + dn } - // TODO don't panic, handle this - log.Panicf("Consul key %s does not end with attribute=something", key) - panic("unreachable") + return "", "", fmt.Errorf("Consul key %s does not end with attribute=something", key) } func parseValue(value []byte) ([]string, error) { @@ -65,7 +62,10 @@ func parseConsulResult(data []*consul.KVPair) (map[string]Entry, error) { aggregator := map[string]Entry{} for _, kv := range data { - dn, attr := consulToDN(kv.Key) + dn, attr, err := consulToDN(kv.Key) + if err != nil { + continue + } if _, exists := aggregator[dn]; !exists { aggregator[dn] = Entry{} } -- cgit v1.2.3