forked from Deuxfleurs/bottin
Fix missing procedure for delete membership & "better" failure handling
After an object has been updated, membership information must be propagated to other object. Such operations may fail when calling consul but if they do we don't return fail immediatly returning an error code any more. Instead we just print all the errors to our logs and try to process the remaining updates.
This commit is contained in:
parent
b27eb45239
commit
f8c726dcda
3 changed files with 74 additions and 21 deletions
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
all: gobottin
|
all: gobottin
|
||||||
|
|
||||||
gobottin: main.go ssha.go util.go acl.go
|
gobottin: main.go ssha.go util.go acl.go read.go write.go
|
||||||
go get -d -v
|
go get -d -v
|
||||||
CGO_ENABLED=0 GOOS=linux go build -a -v
|
CGO_ENABLED=0 GOOS=linux go build -a -v
|
||||||
|
|
||||||
|
|
1
main.go
1
main.go
|
@ -25,6 +25,7 @@ import (
|
||||||
const DEBUG = false
|
const DEBUG = false
|
||||||
|
|
||||||
const ATTR_USERPASSWORD = "userpassword"
|
const ATTR_USERPASSWORD = "userpassword"
|
||||||
|
const ATTR_MEMBER = "member"
|
||||||
const ATTR_MEMBEROF = "memberof"
|
const ATTR_MEMBEROF = "memberof"
|
||||||
const ATTR_ENTRYUUID = "entryuuid"
|
const ATTR_ENTRYUUID = "entryuuid"
|
||||||
const ATTR_CREATORSNAME = "creatorsname"
|
const ATTR_CREATORSNAME = "creatorsname"
|
||||||
|
|
88
write.go
88
write.go
|
@ -60,11 +60,10 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
||||||
return ldap.LDAPResultEntryAlreadyExists, nil
|
return ldap.LDAPResultEntryAlreadyExists, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add object
|
|
||||||
|
|
||||||
// If adding a group, track of who the members will be so that their memberOf field can be updated later
|
// If adding a group, track of who the members will be so that their memberOf field can be updated later
|
||||||
var members []string = nil
|
var members []string = nil
|
||||||
|
|
||||||
|
// Check attributes
|
||||||
entry := Entry{}
|
entry := Entry{}
|
||||||
for _, attribute := range r.Attributes() {
|
for _, attribute := range r.Attributes() {
|
||||||
key := string(attribute.Type_())
|
key := string(attribute.Type_())
|
||||||
|
@ -79,7 +78,7 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
||||||
return ldap.LDAPResultObjectClassViolation, err
|
return ldap.LDAPResultObjectClassViolation, err
|
||||||
}
|
}
|
||||||
// If they are writing a member key, we have to check they are adding valid members
|
// If they are writing a member key, we have to check they are adding valid members
|
||||||
if strings.EqualFold(key, "member") {
|
if strings.EqualFold(key, ATTR_MEMBER) {
|
||||||
members = vals_str
|
members = vals_str
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
_, err := server.checkSuffix(member, false)
|
_, err := server.checkSuffix(member, false)
|
||||||
|
@ -105,16 +104,21 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
||||||
entry[ATTR_ENTRYUUID] = []string{genUuid()}
|
entry[ATTR_ENTRYUUID] = []string{genUuid()}
|
||||||
entry[dnSplit[0].Type] = []string{dnSplit[0].Value}
|
entry[dnSplit[0].Type] = []string{dnSplit[0].Value}
|
||||||
|
|
||||||
|
// Add our intem in the DB
|
||||||
err = server.addElements(dn, entry)
|
err = server.addElements(dn, entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
return ldap.LDAPResultOperationsError, err
|
||||||
}
|
}
|
||||||
|
// ~~ from this point on, our operation succeeded ~~
|
||||||
|
// ~~ future errors cause inconsistencies in the DB and are logged ~~
|
||||||
|
|
||||||
|
// If our item has a member list, add it to all of its member's memberOf attribute
|
||||||
if members != nil {
|
if members != nil {
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
memberGroups, err := server.getAttribute(member, ATTR_MEMBEROF)
|
memberGroups, err := server.getAttribute(member, ATTR_MEMBEROF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not add %s to memberOf of %s: %s", dn, member, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if memberGroups == nil {
|
if memberGroups == nil {
|
||||||
memberGroups = []string{}
|
memberGroups = []string{}
|
||||||
|
@ -136,7 +140,7 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
||||||
ATTR_MEMBEROF: memberGroups,
|
ATTR_MEMBEROF: memberGroups,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not add %s to memberOf of %s: %s", dn, member, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,19 +213,26 @@ func (server *Server) handleDeleteInternal(state *State, r *message.DelRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
return ldap.LDAPResultOperationsError, err
|
||||||
}
|
}
|
||||||
|
memberList, err := server.getAttribute(dn, ATTR_MEMBER)
|
||||||
|
if err != nil {
|
||||||
|
return ldap.LDAPResultOperationsError, err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the LDAP entry
|
// Delete the LDAP entry
|
||||||
_, err = server.kv.DeleteTree(path+"/", nil)
|
_, err = server.kv.DeleteTree(path+"/", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
return ldap.LDAPResultOperationsError, err
|
||||||
}
|
}
|
||||||
|
// ~~ from this point on, our operation succeeded ~~
|
||||||
|
// ~~ future errors cause inconsistencies in the DB and are logged ~~
|
||||||
|
|
||||||
// Delete it from the member list of all the groups it was a member of
|
// Delete it from the member list of all the groups it was a member of
|
||||||
if memberOf != nil {
|
if memberOf != nil {
|
||||||
for _, group := range memberOf {
|
for _, group := range memberOf {
|
||||||
groupMembers, err := server.getAttribute(dn, "member")
|
groupMembers, err := server.getAttribute(group, ATTR_MEMBER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not remove %s from members of %s: %s", dn, group, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
newMembers := []string{}
|
newMembers := []string{}
|
||||||
|
@ -232,10 +243,35 @@ func (server *Server) handleDeleteInternal(state *State, r *message.DelRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = server.addElements(group, Entry{
|
err = server.addElements(group, Entry{
|
||||||
"member": newMembers,
|
ATTR_MEMBER: newMembers,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not remove %s from members of %s: %s", dn, group, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete it from all of its member's memberOf info
|
||||||
|
if memberList != nil {
|
||||||
|
for _, member := range memberList {
|
||||||
|
memberOf, err := server.getAttribute(member, ATTR_MEMBEROF)
|
||||||
|
if err != nil || memberOf == nil {
|
||||||
|
server.logger.Printf("Could not remove %s from memberOf of %s: %s", dn, member, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
newMemberOf := []string{}
|
||||||
|
for _, group := range memberOf {
|
||||||
|
if group != dn {
|
||||||
|
newMemberOf = append(newMemberOf, group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = server.addElements(member, Entry{
|
||||||
|
ATTR_MEMBEROF: newMemberOf,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
server.logger.Printf("Could not remove %s from memberOf of %s: %s", dn, member, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +383,7 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
}
|
}
|
||||||
if !present {
|
if !present {
|
||||||
newEntry[attr] = append(newEntry[attr], string(val))
|
newEntry[attr] = append(newEntry[attr], string(val))
|
||||||
if strings.EqualFold(attr, "member") {
|
if strings.EqualFold(attr, ATTR_MEMBER) {
|
||||||
addMembers = append(addMembers, string(val))
|
addMembers = append(addMembers, string(val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +392,7 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
// Delete everything
|
// Delete everything
|
||||||
newEntry[attr] = []string{}
|
newEntry[attr] = []string{}
|
||||||
if strings.EqualFold(attr, "member") {
|
if strings.EqualFold(attr, ATTR_MEMBER) {
|
||||||
delMembers = append(delMembers, prevEntry[attr]...)
|
delMembers = append(delMembers, prevEntry[attr]...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -373,7 +409,7 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
if keep {
|
if keep {
|
||||||
newEntry[attr] = append(newEntry[attr], prevVal)
|
newEntry[attr] = append(newEntry[attr], prevVal)
|
||||||
} else {
|
} else {
|
||||||
if strings.EqualFold(attr, "member") {
|
if strings.EqualFold(attr, ATTR_MEMBER) {
|
||||||
delMembers = append(delMembers, prevVal)
|
delMembers = append(delMembers, prevVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +420,7 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
for _, newVal := range values {
|
for _, newVal := range values {
|
||||||
newEntry[attr] = append(newEntry[attr], string(newVal))
|
newEntry[attr] = append(newEntry[attr], string(newVal))
|
||||||
}
|
}
|
||||||
if strings.EqualFold(attr, "member") {
|
if strings.EqualFold(attr, ATTR_MEMBER) {
|
||||||
for _, newMem := range newEntry[attr] {
|
for _, newMem := range newEntry[attr] {
|
||||||
mustAdd := true
|
mustAdd := true
|
||||||
for _, prevMem := range prevEntry[attr] {
|
for _, prevMem := range prevEntry[attr] {
|
||||||
|
@ -430,27 +466,43 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
|
|
||||||
// Save the edited values
|
// Save the edited values
|
||||||
server.addElements(dn, newEntry)
|
server.addElements(dn, newEntry)
|
||||||
|
// ~~ from this point on, our operation succeeded ~~
|
||||||
|
// ~~ future errors cause inconsistencies in the DB and are logged ~~
|
||||||
|
|
||||||
// Update memberOf for added members and deleted members
|
// Update memberOf for added members and deleted members
|
||||||
for _, addMem := range addMembers {
|
for _, addMem := range addMembers {
|
||||||
memberOf, err := server.getAttribute(addMem, ATTR_MEMBEROF)
|
memberOf, err := server.getAttribute(addMem, ATTR_MEMBEROF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not add %s to memberOf of %s: %s", dn, addMem, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if memberOf == nil {
|
if memberOf == nil {
|
||||||
memberOf = []string{}
|
memberOf = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alreadyMember := false
|
||||||
|
for _, mb := range memberOf {
|
||||||
|
if mb == dn {
|
||||||
|
alreadyMember = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyMember {
|
||||||
memberOf = append(memberOf, dn)
|
memberOf = append(memberOf, dn)
|
||||||
err = server.addElements(addMem, Entry{ATTR_MEMBEROF: memberOf})
|
err = server.addElements(addMem, Entry{
|
||||||
|
ATTR_MEMBEROF: memberOf,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not add %s to memberOf of %s: %s", dn, addMem, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, delMem := range delMembers {
|
for _, delMem := range delMembers {
|
||||||
memberOf, err := server.getAttribute(delMem, ATTR_MEMBEROF)
|
memberOf, err := server.getAttribute(delMem, ATTR_MEMBEROF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not remove %s from memberOf of %s: %s", dn, delMem, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if memberOf == nil {
|
if memberOf == nil {
|
||||||
memberOf = []string{}
|
memberOf = []string{}
|
||||||
|
@ -464,7 +516,7 @@ func (server *Server) handleModifyInternal(state *State, r *message.ModifyReques
|
||||||
|
|
||||||
err = server.addElements(delMem, Entry{ATTR_MEMBEROF: newMemberOf})
|
err = server.addElements(delMem, Entry{ATTR_MEMBEROF: newMemberOf})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap.LDAPResultOperationsError, err
|
server.logger.Printf("Could not remove %s from memberOf of %s: %s", dn, delMem, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue