aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-15 12:04:06 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-15 12:07:31 +0100
commit825aa770893850fb2626def316c4b0f060ef776f (patch)
treeec09d3475f50886c001af29f4b593a9167be084a /main.go
parent0c4d55895cfda3632af8ada1cebd3e14addb6033 (diff)
downloadbottin-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.go59
1 files changed, 44 insertions, 15 deletions
diff --git a/main.go b/main.go
index 9de5f3a..cec68ef 100644
--- a/main.go
+++ b/main.go
@@ -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