Skip to content

Commit 8ecd6fe

Browse files
committed
windows: add GetExplicitEntriesFromAcl
1 parent 50db343 commit 8ecd6fe

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

windows/security_windows.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,7 @@ type OBJECTS_AND_NAME struct {
11221122
//sys SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) = advapi32.SetSecurityInfo
11231123
//sys getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetNamedSecurityInfoW
11241124
//sys SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
1125+
//sys getExplicitEntriesFromAclW(acl *ACL, countAccessEntries *uint32, accessEntries **EXPLICIT_ACCESS) (ret error) = advapi32.GetExplicitEntriesFromAclW
11251126

11261127
//sys buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) = advapi32.BuildSecurityDescriptorW
11271128
//sys initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
@@ -1374,6 +1375,29 @@ func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, security
13741375
return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
13751376
}
13761377

1378+
// GetExplicitEntriesFromAcl queries the explicit entries from a given ACL
1379+
func GetExplicitEntriesFromAcl(acl *ACL) ([]EXPLICIT_ACCESS, error) {
1380+
var entries *EXPLICIT_ACCESS
1381+
var size uint32
1382+
err := getExplicitEntriesFromAclW(
1383+
acl,
1384+
&size,
1385+
&entries,
1386+
)
1387+
if err != nil {
1388+
return nil, err
1389+
}
1390+
1391+
defer LocalFree(Handle(unsafe.Pointer(entries)))
1392+
var accesses []EXPLICIT_ACCESS
1393+
for i := 0; i < int(size); i++ {
1394+
accesses = append(accesses, *entries)
1395+
entries = (*EXPLICIT_ACCESS)(unsafe.Pointer((uintptr(unsafe.Pointer(entries)) + unsafe.Sizeof(*entries))))
1396+
}
1397+
1398+
return accesses, nil
1399+
}
1400+
13771401
// BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
13781402
// prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
13791403
// result on the Go heap.

windows/syscall_windows_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,50 @@ import (
1818
"golang.org/x/sys/windows"
1919
)
2020

21+
func TestGetExplicitEntriesFromAcl(t *testing.T) {
22+
fileObject := os.ExpandEnv("${SystemRoot}")
23+
24+
sd, err := windows.GetNamedSecurityInfo(
25+
fileObject,
26+
windows.SE_FILE_OBJECT,
27+
windows.DACL_SECURITY_INFORMATION,
28+
)
29+
30+
dacl, _, err := sd.DACL()
31+
if err != nil {
32+
t.Fatal(err)
33+
}
34+
accesses, err := windows.GetExplicitEntriesFromAcl(dacl)
35+
if err != nil {
36+
t.Fatal(err)
37+
}
38+
39+
for _, access := range accesses {
40+
_ = trusteeValueFrom(&access.Trustee)
41+
}
42+
}
43+
44+
func trusteeValueFrom(trustee *windows.TRUSTEE) interface{} {
45+
var ret interface{}
46+
switch trustee.TrusteeForm {
47+
case windows.TRUSTEE_IS_SID:
48+
ret = windows.TrusteeValueToSID(trustee.TrusteeValue).String()
49+
50+
case windows.TRUSTEE_IS_NAME:
51+
ret = windows.TrusteeValueToString(trustee.TrusteeValue)
52+
53+
case windows.TRUSTEE_BAD_FORM:
54+
55+
case windows.TRUSTEE_IS_OBJECTS_AND_SID:
56+
ret = windows.TrusteeValueToObjectsAndSid(trustee.TrusteeValue)
57+
58+
case windows.TRUSTEE_IS_OBJECTS_AND_NAME:
59+
ret = windows.TrusteeValueToObjectsAndName(trustee.TrusteeValue)
60+
}
61+
62+
return ret
63+
}
64+
2165
func TestWin32finddata(t *testing.T) {
2266
dir, err := ioutil.TempDir("", "go-build")
2367
if err != nil {

windows/zsyscall_windows.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)