diff options
author | Alex Auvolat <alex@adnab.me> | 2020-02-13 14:41:33 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-02-13 14:41:49 +0100 |
commit | 13d8cf028a7841df54da31650918fe0f142df2d8 (patch) | |
tree | 0802d05040ccc19ec5c393222275748e56b655fa | |
parent | 49be2069f63d8f2909840ad504063c773d0ba7ed (diff) | |
download | bottin-13d8cf028a7841df54da31650918fe0f142df2d8.tar.gz bottin-13d8cf028a7841df54da31650918fe0f142df2d8.zip |
Add a function to resync member/memberOf values over the database
-rw-r--r-- | main.go | 10 | ||||
-rw-r--r-- | memberof.go | 88 |
2 files changed, 97 insertions, 1 deletions
@@ -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 +} |