diff options
author | Alex Auvolat <alex@adnab.me> | 2020-02-15 12:04:06 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-02-15 12:07:31 +0100 |
commit | 825aa770893850fb2626def316c4b0f060ef776f (patch) | |
tree | ec09d3475f50886c001af29f4b593a9167be084a /main.go | |
parent | 0c4d55895cfda3632af8ada1cebd3e14addb6033 (diff) | |
download | bottin-825aa770893850fb2626def316c4b0f060ef776f.tar.gz bottin-825aa770893850fb2626def316c4b0f060ef776f.zip |
Hopefully, fix most case-sensitivity issues
- DNs are always used in canonical form: lowercase, no spaces. This is
how they are internally handled and stored in paths and fields such as
member and memberof
- Attribute names now can have any combination of lower/uppercase and
stuff should work
- When modifying an attribute with a name that hase a different
lower/upper combination than the previously stored value, keep the
previous attribute name
- Trim spaces from values and do not store empty values
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 59 |
1 files changed, 44 insertions, 15 deletions
@@ -10,6 +10,7 @@ import ( "io/ioutil" "os" "os/signal" + "strings" "syscall" ldap "bottin/ldapserver" @@ -19,15 +20,18 @@ import ( log "github.com/sirupsen/logrus" ) -const ATTR_USERPASSWORD = "userpassword" -const ATTR_MEMBER = "member" +// System managed attributes (cannot be changed by user, see checkRestrictedAttr) const ATTR_MEMBEROF = "memberof" const ATTR_ENTRYUUID = "entryuuid" const ATTR_CREATORSNAME = "creatorsname" const ATTR_CREATETIMESTAMP = "createtimestamp" const ATTR_MODIFIERSNAME = "modifiersname" const ATTR_MODIFYTIMESTAMP = "modifytimestamp" + +// Attributes that we are interested in at various points const ATTR_OBJECTCLASS = "objectclass" +const ATTR_MEMBER = "member" +const ATTR_USERPASSWORD = "userpassword" type ConfigFile struct { Suffix string `json:"suffix"` @@ -260,20 +264,27 @@ func (server *Server) newUserState() ldap.UserState { } func (server *Server) init() error { - path, err := dnToConsul(server.config.Suffix) + // Check that suffix is in canonical format in config file + suffix_canonical, err := server.checkDN(server.config.Suffix, false) if err != nil { return err } + if suffix_canonical != server.config.Suffix { + return fmt.Errorf("Please write suffix in canonical format: %s", suffix_canonical) + } - pair, _, err := server.kv.Get(path+"/attribute="+ATTR_OBJECTCLASS, nil) + // Check that root object exists. + // If it does, we're done. Otherwise, we have some initialization to do. + exists, err := server.objectExists(server.config.Suffix) if err != nil { return err } - - if pair != nil { + if exists { return nil } + // We have to initialize the server. + // Create a root object and an admin object. base_attributes := Entry{ ATTR_OBJECTCLASS: []string{"top", "dcObject", "organization"}, "structuralobjectclass": []string{"organization"}, @@ -333,16 +344,27 @@ func (server *Server) addElements(dn string, attrs Entry) error { return err } - for k, v := range attrs { + for k, valuesNC := range attrs { path := prefix + "/attribute=" + k - if len(v) == 0 { - // If we have zero values, delete associated k/v pair + + // Trim spaces and remove empty values + values := []string{} + for _, v := range valuesNC { + vv := strings.TrimSpace(v) + if len(vv) > 0 { + values = append(values, vv) + } + } + + // If we have zero values, delete associated k/v pair + // Otherwise, write new values + if len(values) == 0 { _, err := server.kv.Delete(path, nil) if err != nil { return err } } else { - json, err := json.Marshal(v) + json, err := json.Marshal(values) if err != nil { return err } @@ -362,16 +384,23 @@ func (server *Server) getAttribute(dn string, attr string) ([]string, error) { return nil, err } - pair, _, err := server.kv.Get(path+"/attribute="+attr, nil) + pairs, _, err := server.kv.List(path+"/attribute=", nil) if err != nil { return nil, err } - if pair == nil { - return []string{}, nil + values := []string{} + for _, pair := range pairs { + if strings.EqualFold(pair.Key, path+"/attribute="+attr) { + newVals, err := parseValue(pair.Value) + if err != nil { + return nil, err + } + values = append(values, newVals...) + } } - return parseValue(pair.Value) + return values, nil } func (server *Server) objectExists(dn string) (bool, error) { @@ -388,7 +417,7 @@ func (server *Server) objectExists(dn string) (bool, error) { } func (server *Server) checkDN(dn string, allow_extend bool) (string, error) { - // 1. Canonicalize: remove spaces between things + // 1. Canonicalize: remove spaces between things and put all in lower case dn, err := canonicalDN(dn) if err != nil { return "", err |