in sddl/sddlString.go [91:208]
func (a *ACLList) PortableString() string {
output := a.Flags
for _, v := range a.ACLEntries {
output += "("
for k, s := range v.Sections {
// Append a ; after the last section
if k > 0 {
output += ";"
}
if k == 5 {
// This section is a lone SID, so we can make a call to windows and translate it.
tx, err := translateSID(strings.TrimSpace(s))
if err != nil {
output += s
} else {
output += tx
}
} else if k == 6 {
// This section will potentially have SIDs unless it's not a conditional ACE.
// They're identifiable as they're inside a literal SID container. ex "SID(S-1-1-0)"
workingString := ""
lastAddPoint := 0
if v.Sections[0] == "XA" || v.Sections[0] == "XD" || v.Sections[0] == "XU" || v.Sections[0] == "ZA" {
// We shouldn't do any replacing if we're inside of a string.
// In order to handle this, we'll handle it as a list of events that occur.
stringEntries := StringRegex.FindAllStringIndex(s, -1)
sidEntries := LiteralSIDRegex.FindAllStringIndex(s, -1)
eventMap := map[int]int{} // 1 = string start, 2 = string end, 3 = SID start, 4 = SID end.
eventList := make([]int, 0)
inString := false
SIDStart := -1
processSID := false
// Register string beginnings and ends
for _, v := range stringEntries {
eventMap[v[0]] = 1
eventMap[v[1]] = 2
eventList = append(eventList, v...)
}
// Register SID beginnings and ends
for _, v := range sidEntries {
eventMap[v[0]] = 3
eventMap[v[1]] = 4
eventList = append(eventList, v...)
}
// sort the list
sort.Ints(eventList)
// Traverse it.
// Handle any SIDs outside of strings.
for _, v := range eventList {
event := eventMap[v]
switch event {
case 1: // String start
inString = true
// Add everything prior to this
workingString += s[lastAddPoint:v]
lastAddPoint = v
case 2:
inString = false
// Add everything prior to this
workingString += s[lastAddPoint:v]
lastAddPoint = v
case 3:
processSID = !inString
SIDStart = v
// If we're going to process this SID, add everything prior to this.
if processSID {
workingString += s[lastAddPoint:v]
lastAddPoint = v
}
case 4:
if processSID {
// We have to process the sid string now.
sidString := strings.TrimSuffix(strings.TrimPrefix(s[SIDStart:v], "SID("), ")")
tx, err := translateSID(strings.TrimSpace(sidString))
// It seems like we should probably still add the string if we error out.
// However, this just gets handled exactly like we're not processing the SID.
// When the next event happens, we just add everything to the string, including the original SID.
if err == nil {
workingString += "SID(" + tx + ")"
lastAddPoint = v
}
}
}
}
}
if workingString != "" {
if lastAddPoint != len(s) {
workingString += s[lastAddPoint:]
}
s = workingString
}
output += s
} else {
output += s
}
}
output += ")"
}
return strings.TrimSpace(output)
}