Skip to content

Commit

Permalink
Fixes for Absorb, changed from slice to map for member/memberof, also…
Browse files Browse the repository at this point in the history
… Go 1.18 requirement due to generics
  • Loading branch information
lkarlslund committed May 5, 2022
1 parent 1aaff27 commit 7fd7577
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 64 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/lkarlslund/adalanche

go 1.17
go 1.18

require (
github.com/Microsoft/go-winio v0.5.2
Expand Down
122 changes: 59 additions & 63 deletions modules/engine/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,22 @@ type Object struct {
sdcache *SecurityDescriptor
sid windowssecurity.SID
children []*Object
members []*Object
membersrecursive []*Object
members map[*Object]struct{}
membersrecursive map[*Object]struct{}

memberof []*Object
memberofrecursive []*Object
memberof map[*Object]struct{}
memberofrecursive map[*Object]struct{}

memberofsid []windowssecurity.SID
memberofsidrecursive []windowssecurity.SID

id uint32
guid uuid.UUID
// objectcategoryguid uuid.UUID
guidcached bool
sidcached bool
objecttype ObjectType
guidcached bool
sidcached bool
invalidated bool
objecttype ObjectType
}

type Connection struct {
Expand Down Expand Up @@ -101,6 +102,9 @@ func (o *Object) lock() {
if threadsafeobject != 0 {
threadsafeobjectmutexes[o.lockbucket()].Lock()
}
if o.invalidated {
panic("object is invalidated")
}
}

func (o *Object) rlock() {
Expand Down Expand Up @@ -197,44 +201,37 @@ func (o *Object) Absorb(source *Object) {
delete(pwner.CanPwn, source)
}

if len(target.members) > 0 {
members := make(map[*Object]struct{})
for _, member := range target.members {
members[member] = struct{}{}

member.memberofrecursive = nil
member.membersrecursive = nil
}
// For everyone that is a member of source, relink them to the target
if target.members == nil {
target.members = make(map[*Object]struct{})
}
for newmember := range source.members {
target.members[newmember] = struct{}{}
// delete(source.members, newmember) // Handled below by setting to nil

for _, newmember := range source.members {
if _, found := members[newmember]; !found {
target.members = append(target.members, newmember)
// Relink the memberof attribute of the member and clear cache
delete(newmember.memberof, source)
newmember.memberof[target] = struct{}{}
newmember.memberofrecursive = nil
}
source.members = nil
source.membersrecursive = nil

newmember.memberofrecursive = nil
newmember.membersrecursive = nil
}
}
source.members = nil
source.membersrecursive = nil
} else {
target.members = source.members
if target.memberof == nil {
target.memberof = make(map[*Object]struct{})
}

if len(target.memberof) > 0 {
memberofgroups := make(map[*Object]struct{})
for _, memberof := range target.memberof {
memberofgroups[memberof] = struct{}{}
}
for _, newmemberof := range source.memberof {
if _, found := memberofgroups[newmemberof]; !found {
target.memberof = append(target.memberof, newmemberof)
}
}
source.memberof = nil
source.memberofrecursive = nil
} else {
target.memberof = source.memberof
for newmemberof := range source.memberof {
target.memberof[newmemberof] = struct{}{}
// delete(source.memberof, newmemberof) // handled below by setting to nil

// Relink the member attribute of the newmemberof
newmemberof.members[target] = struct{}{}
delete(newmemberof.members, source)
newmemberof.membersrecursive = nil
}
source.memberof = nil
source.memberofrecursive = nil

for _, child := range source.children {
target.Adopt(child)
Expand Down Expand Up @@ -270,7 +267,7 @@ func (o *Object) Absorb(source *Object) {
target.memberofsid = nil // Clear cache
target.memberofsidrecursive = nil // Clear cache

source.id = 0 // Invalid object
source.invalidated = true // Invalid object
}

func (o *Object) AttributeValueMap() AttributeValueMap {
Expand Down Expand Up @@ -545,25 +542,28 @@ func (o *Object) AttrTimestamp(attr Attribute) (time.Time, bool) { // FIXME, swi

func (o *Object) AddMember(member *Object) {
member.lock()
for _, mo := range member.memberof {
// Dupe elimination
if mo == o {
member.unlock()
return
}
if _, found := member.memberof[o]; found {
member.unlock()
return
}
member.memberof = append(member.memberof, o)
if member.memberof == nil {
member.memberof = make(map[*Object]struct{})
}
member.memberof[o] = struct{}{}
member.unlock()
o.lock()
o.members = append(o.members, member)
if o.members == nil {
o.members = make(map[*Object]struct{})
}
o.members[member] = struct{}{}
o.unlock()
}

func (o *Object) Members(recursive bool) []*Object {
o.lock()
defer o.unlock()
if !recursive {
return o.members
return util.KeysToSlice(o.members)
}

members := make(map[*Object]struct{})
Expand All @@ -579,7 +579,7 @@ func (o *Object) Members(recursive bool) []*Object {
}

func (o *Object) recursemembers(members *map[*Object]struct{}) {
for _, directmember := range o.members {
for directmember := range o.members {
if _, found := (*members)[directmember]; found {
// endless loop, not today thanks
continue
Expand All @@ -597,30 +597,24 @@ func (o *Object) MemberOf(recursive bool) []*Object {

func (o *Object) memberofr(recursive bool) []*Object {
if !recursive || len(o.memberof) == 0 {
return o.memberof
return util.KeysToSlice(o.memberof)
}

if o.memberofrecursive != nil {
return o.memberofrecursive
return util.KeysToSlice(o.memberofrecursive)
}

memberof := make(map[*Object]struct{})
o.recursememberof(&memberof)

memberofarray := make([]*Object, len(memberof))
var i int
for member := range memberof {
memberofarray[i] = member
i++
}
o.memberofrecursive = memberofarray
return memberofarray
o.memberofrecursive = memberof
return util.KeysToSlice(memberof)
}

// Recursive memberof, returns true if loop is detected
func (o *Object) recursememberof(memberof *map[*Object]struct{}) bool {
var loop bool
for _, directmemberof := range o.memberof {
for directmemberof := range o.memberof {
if _, found := (*memberof)[directmemberof]; found {
// endless loop, not today thanks
loop = true
Expand All @@ -641,8 +635,10 @@ func (o *Object) MemberOfSID(recursive bool) []windowssecurity.SID {
if !recursive {
if o.memberofsid == nil {
o.memberofsid = make([]windowssecurity.SID, len(o.memberof))
for i, memberof := range o.memberof {
i := 0
for memberof := range o.memberof {
o.memberofsid[i] = memberof.SID()
i++
}
}

Expand Down
11 changes: 11 additions & 0 deletions modules/util/generics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package util

func KeysToSlice[K comparable, V any](m map[K]V) []K {
keys := make([]K, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}

0 comments on commit 7fd7577

Please sign in to comment.