aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-13 14:41:33 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-13 14:41:49 +0100
commit13d8cf028a7841df54da31650918fe0f142df2d8 (patch)
tree0802d05040ccc19ec5c393222275748e56b655fa
parent49be2069f63d8f2909840ad504063c773d0ba7ed (diff)
downloadbottin-13d8cf028a7841df54da31650918fe0f142df2d8.tar.gz
bottin-13d8cf028a7841df54da31650918fe0f142df2d8.zip
Add a function to resync member/memberOf values over the database
-rw-r--r--main.go10
-rw-r--r--memberof.go88
2 files changed, 97 insertions, 1 deletions
diff --git a/main.go b/main.go
index 5e9811d..b085e2f 100644
--- a/main.go
+++ b/main.go
@@ -65,6 +65,7 @@ type State struct {
type Entry map[string][]string
var configFlag = flag.String("config", "./config.json", "Configuration file path")
+var resyncFlag = flag.Bool("resync", false, "Check and re-synchronize memberOf values before launch")
func readConfig(logger *log.Logger) Config {
config_file := ConfigFile{
@@ -171,6 +172,13 @@ func main() {
logger.Fatal(err)
}
+ if *resyncFlag {
+ err = bottin.memberOfResync()
+ if err != nil {
+ logger.Fatal(err)
+ }
+ }
+
// Create routes
routes := ldap.NewRouteMux()
@@ -267,7 +275,7 @@ func (server *Server) init() error {
base_attributes := Entry{
"objectClass": []string{"top", "dcObject", "organization"},
- "structuralObjectClass": []string{"Organization"},
+ "structuralObjectClass": []string{"organization"},
ATTR_CREATORSNAME: []string{server.config.Suffix},
ATTR_CREATETIMESTAMP: []string{genTimestamp()},
ATTR_ENTRYUUID: []string{genUuid()},
diff --git a/memberof.go b/memberof.go
index c4074e4..5bc7a26 100644
--- a/memberof.go
+++ b/memberof.go
@@ -1,5 +1,9 @@
package main
+import (
+ "sort"
+)
+
func (server *Server) memberOfAdd(member string, group string) {
// Retreive previous memberOf value
memberGroups, err := server.getAttribute(member, ATTR_MEMBEROF)
@@ -58,3 +62,87 @@ func (server *Server) memberOfRemove(member string, group string) {
server.logger.Warnf("Could not remove %s from memberOf of %s: %s", group, member, err)
}
}
+
+func (server *Server) memberOfResync() error {
+ server.logger.Warnf("Starting resync of member/memberOf values")
+
+ // Load the whole LDAP database
+ basePath, err := dnToConsul(server.config.Suffix)
+ if err != nil {
+ return err
+ }
+
+ data, _, err := server.kv.List(basePath, nil)
+ if err != nil {
+ return err
+ }
+
+ entries, err := parseConsulResult(data)
+ if err != nil {
+ return err
+ }
+
+ // Check member values for all objects, and remove deleted objects
+ // Calculate new memberOf sets for all objects
+ newMemberOf := make(map[string][]string)
+ for dn := range entries {
+ newMemberOf[dn] = []string{}
+ }
+
+ for dn, entry := range entries {
+ member, ok := entry[ATTR_MEMBER]
+ if !ok {
+ continue
+ }
+ keepMember := []string{}
+ for _, mem := range member {
+ if _, exists := entries[mem]; exists {
+ keepMember = append(keepMember, mem)
+ newMemberOf[mem] = append(newMemberOf[mem], dn)
+ } else {
+ server.logger.Warnf("Fixing: %s had as member %s which doesn't exist", dn, mem)
+ }
+ }
+ if len(keepMember) != len(member) {
+ server.logger.Warnf("Writing new member list for %s", dn)
+ err = server.addElements(dn, Entry{
+ ATTR_MEMBER: keepMember,
+ })
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // Write updated memberOf values
+ for dn, newMemberOfV := range newMemberOf {
+ prevMemberOf := []string{}
+ if v, ok := entries[dn][ATTR_MEMBEROF]; ok {
+ prevMemberOf = v
+ }
+ different := (len(prevMemberOf) != len(newMemberOfV))
+ if !different {
+ sort.Strings(newMemberOfV)
+ sort.Strings(prevMemberOf)
+ for i := range newMemberOfV {
+ if newMemberOfV[i] != prevMemberOf[i] {
+ different = true
+ break
+ }
+ }
+ }
+ if different {
+ server.logger.Warnf("Fixing memberOf for %s (%d -> %d)",
+ dn, len(prevMemberOf), len(newMemberOfV))
+ err = server.addElements(dn, Entry{
+ ATTR_MEMBEROF: newMemberOfV,
+ })
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ server.logger.Warnf("Done resyncing member/memberOf values")
+ return nil
+}