aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-07 20:34:01 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-08 08:31:00 +0200
commita7d59eb1e71685edb76d3aa59df4f24c864ee285 (patch)
tree0b39272e651d7d6da8809a0228248b6cd32a7540 /service
parentinstaller: silence LGHT1056 warning (diff)
downloadwireguard-windows-a7d59eb1e71685edb76d3aa59df4f24c864ee285.tar.xz
wireguard-windows-a7d59eb1e71685edb76d3aa59df4f24c864ee285.zip
service: give process elevated security attributes plus logon session ID with minimal permissions
Diffstat (limited to 'service')
-rw-r--r--service/errors.go3
-rw-r--r--service/mksyscall.go2
-rw-r--r--service/securityapi.go176
-rw-r--r--service/service_manager.go27
-rw-r--r--service/zsyscall_windows.go145
5 files changed, 311 insertions, 42 deletions
diff --git a/service/errors.go b/service/errors.go
index eb31bb4e..670c3305 100644
--- a/service/errors.go
+++ b/service/errors.go
@@ -26,7 +26,6 @@ const (
ErrorBindSocketsToDefaultRoutes
ErrorSetNetConfig
ErrorDetermineExecutablePath
- ErrorCreateSecurityDescriptor
ErrorOpenNULFile
ErrorTrackTunnels
ErrorEnumerateSessions
@@ -59,8 +58,6 @@ func (e Error) Error() string {
return "Unable to bind sockets to default route"
case ErrorSetNetConfig:
return "Unable to set interface addresses, routes, dns, and/or adapter settings"
- case ErrorCreateSecurityDescriptor:
- return "Unable to determine security descriptor"
case ErrorOpenNULFile:
return "Unable to open NUL file"
case ErrorTrackTunnels:
diff --git a/service/mksyscall.go b/service/mksyscall.go
index ccc4053e..417a99fb 100644
--- a/service/mksyscall.go
+++ b/service/mksyscall.go
@@ -5,4 +5,4 @@
package service
-//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go service_manager.go tunneltracker.go
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go securityapi.go tunneltracker.go
diff --git a/service/securityapi.go b/service/securityapi.go
index 6373fd7c..b0de8604 100644
--- a/service/securityapi.go
+++ b/service/securityapi.go
@@ -7,7 +7,9 @@ package service
import (
"errors"
+ "fmt"
"golang.org/x/sys/windows"
+ "runtime"
"syscall"
"unicode/utf16"
"unsafe"
@@ -51,12 +53,65 @@ type wtsSessionInfo struct {
const (
SE_KERNEL_OBJECT = 6
- DACL_SECURITY_INFORMATION = 4
- ATTRIBUTE_SECURITY_INFORMATION = 16
+ SE_GROUP_LOGON_ID = 0xC0000000
+ SE_GROUP_ENABLED = 0x00000004
+ SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010
+
+ ACL_REVISION = 2
+
+ PROCESS_TERMINATE = 0x0001
+ PROCESS_CREATE_THREAD = 0x0002
+ PROCESS_SET_SESSIONID = 0x0004
+ PROCESS_VM_OPERATION = 0x0008
+ PROCESS_VM_READ = 0x0010
+ PROCESS_VM_WRITE = 0x0020
+ PROCESS_DUP_HANDLE = 0x0040
+ PROCESS_CREATE_PROCESS = 0x0080
+ PROCESS_SET_QUOTA = 0x0100
+ PROCESS_SET_INFORMATION = 0x0200
+ PROCESS_QUERY_INFORMATION = 0x0400
+ PROCESS_SUSPEND_RESUME = 0x0800
+ PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
+
+ OWNER_SECURITY_INFORMATION = 0x00000001
+ GROUP_SECURITY_INFORMATION = 0x00000002
+ DACL_SECURITY_INFORMATION = 0x00000004
+ SACL_SECURITY_INFORMATION = 0x00000008
+ LABEL_SECURITY_INFORMATION = 0x00000010
+ ATTRIBUTE_SECURITY_INFORMATION = 0x00000020
+ SCOPE_SECURITY_INFORMATION = 0x00000040
+ BACKUP_SECURITY_INFORMATION = 0x00010000
+ PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
+ PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000
+ UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
+ UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
+
+ AclRevisionInformation = 1
+ AclSizeInformation = 2
)
-//sys getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo
+type ACL_SIZE_INFORMATION struct {
+ aceCount uint32
+ aclBytesInUse uint32
+ aclBytesFree uint32
+}
+type ACE_HEADER struct {
+ aceType byte
+ aceFlags byte
+ aceSize uint16
+}
+
+//sys getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, owner *uintptr, group *uintptr, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo
//sys getSecurityDescriptorLength(securityDescriptor uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
+//sys addAccessAllowedAce(acl uintptr, aceRevision uint32, accessmask uint32, sid *windows.SID) (err error) = advapi32.AddAccessAllowedAce
+//sys setSecurityDescriptorDacl(securityDescriptor uintptr, daclPresent bool, dacl uintptr, defaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
+//sys setSecurityDescriptorSacl(securityDescriptor uintptr, saclPresent bool, sacl uintptr, defaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
+//sys getAclInformation(acl uintptr, info unsafe.Pointer, len uint32, infoclass uint32) (err error) = advapi32.GetAclInformation
+//sys getAce(acl uintptr, index uint32, ace *uintptr) (err error) = advapi32.GetAce
+//sys addAce(acl uintptr, revision uint32, index uint32, ace uintptr, lenAce uint32) (err error) = advapi32.AddAce
+//sys initializeAcl(acl uintptr, len uint32, revision uint32) (err error) = advapi32.InitializeAcl
+//sys makeAbsoluteSd(selfRelativeSecurityDescriptor uintptr, absoluteSecurityDescriptor uintptr, absoluteSecurityDescriptorSize *uint32, dacl uintptr, daclSize *uint32, sacl uintptr, saclSize *uint32, owner uintptr, ownerSize *uint32, primaryGroup uintptr, primaryGroupSize *uint32) (err error) = advapi32.MakeAbsoluteSD
+//sys makeSelfRelativeSd(absoluteSecurityDescriptor uintptr, relativeSecurityDescriptor uintptr, relativeSecurityDescriptorSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
//sys createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
//sys destroyEnvironmentBlock(block uintptr) (err error) = userenv.DestroyEnvironmentBlock
@@ -115,8 +170,6 @@ func getElevatedToken(token windows.Token) (windows.Token, error) {
}
func tokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
- //TODO: SECURITY CRITICIAL!
- //TODO: Isn't it better to use an impersonation token or userToken.IsMember instead?
adminSid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
if err != nil {
return false
@@ -125,33 +178,122 @@ func tokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
if err != nil {
return false
}
- p := unsafe.Pointer(&gs.Groups[0])
- groups := (*[(1 << 28) - 1]windows.SIDAndAttributes)(p)[:gs.GroupCount]
+ groups := (*[(1 << 28) - 1]windows.SIDAndAttributes)(unsafe.Pointer(&gs.Groups[0]))[:gs.GroupCount]
isAdmin := false
for _, g := range groups {
- if windows.EqualSid(g.Sid, adminSid) {
+ if (g.Attributes&SE_GROUP_USE_FOR_DENY_ONLY != 0 || g.Attributes&SE_GROUP_ENABLED != 0) && windows.EqualSid(g.Sid, adminSid) {
isAdmin = true
break
}
}
+ runtime.KeepAlive(gs)
return isAdmin
}
-func getCurrentSecurityAttributes() (*syscall.SecurityAttributes, error) {
- currentProcess, err := windows.GetCurrentProcess()
+func sliceToSecurityAttributes(sa []byte) *syscall.SecurityAttributes {
+ return &syscall.SecurityAttributes{
+ Length: uint32(len(sa)),
+ SecurityDescriptor: uintptr(unsafe.Pointer(&sa[0])),
+ }
+}
+
+func getSecurityAttributes(mainToken windows.Token, tokenThatHasLogonSession windows.Token) ([]byte, error) {
+ gs, err := tokenThatHasLogonSession.GetTokenGroups()
+ if err != nil {
+ return nil, err
+ }
+ var logonSid *windows.SID
+ groups := (*[(1 << 28) - 1]windows.SIDAndAttributes)(unsafe.Pointer(&gs.Groups[0]))[:gs.GroupCount]
+ for _, g := range groups {
+ if g.Attributes&SE_GROUP_LOGON_ID != 0 && g.Attributes&SE_GROUP_ENABLED != 0 {
+ logonSid = g.Sid
+ break
+ }
+ }
+ if logonSid == nil {
+ return nil, errors.New("Unable to find logon SID")
+ }
+
+ var originalSecurityDescriptor uintptr
+ err = getSecurityInfo(windows.Handle(mainToken), SE_KERNEL_OBJECT, ATTRIBUTE_SECURITY_INFORMATION|LABEL_SECURITY_INFORMATION|SCOPE_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, nil, nil, nil, nil, &originalSecurityDescriptor)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ absoluteSecurityDescriptorSize uint32
+ daclSize uint32
+ saclSize uint32
+ ownerSize uint32
+ primaryGroupSize uint32
+ )
+ err = makeAbsoluteSd(originalSecurityDescriptor, 0, &absoluteSecurityDescriptorSize, 0, &daclSize, 0, &saclSize, 0, &ownerSize, 0, &primaryGroupSize)
+ if err != windows.ERROR_INSUFFICIENT_BUFFER {
+ windows.LocalFree(windows.Handle(originalSecurityDescriptor))
+ return nil, fmt.Errorf("Expected insufficient buffer from MakeAbsoluteSd, but got: %v", err)
+ }
+ absoluteSecurityDescriptor := make([]byte, absoluteSecurityDescriptorSize)
+ dacl := make([]byte, daclSize)
+ sacl := make([]byte, saclSize)
+ owner := make([]byte, ownerSize)
+ primaryGroup := make([]byte, primaryGroupSize)
+ err = makeAbsoluteSd(originalSecurityDescriptor, uintptr(unsafe.Pointer(&absoluteSecurityDescriptor[0])), &absoluteSecurityDescriptorSize, uintptr(unsafe.Pointer(&dacl[0])), &daclSize, uintptr(unsafe.Pointer(&sacl[0])), &saclSize, uintptr(unsafe.Pointer(&owner[0])), &ownerSize, uintptr(unsafe.Pointer(&primaryGroup[0])), &primaryGroupSize)
+ if err != nil {
+ windows.LocalFree(windows.Handle(originalSecurityDescriptor))
+ return nil, err
+ }
+ windows.LocalFree(windows.Handle(originalSecurityDescriptor))
+
+ var daclInfo ACL_SIZE_INFORMATION
+ err = getAclInformation(uintptr(unsafe.Pointer(&dacl[0])), unsafe.Pointer(&daclInfo), uint32(unsafe.Sizeof(daclInfo)), AclSizeInformation)
if err != nil {
return nil, err
}
- securityAttributes := &syscall.SecurityAttributes{}
- err = getSecurityInfo(currentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, nil, nil, &securityAttributes.SecurityDescriptor)
+ newDacl := make([]byte, daclInfo.aclBytesInUse*2)
+ err = initializeAcl(uintptr(unsafe.Pointer(&newDacl[0])), uint32(len(newDacl)), ACL_REVISION)
if err != nil {
return nil, err
}
- windows.LocalFree(windows.Handle(securityAttributes.SecurityDescriptor))
- securityAttributes.Length = getSecurityDescriptorLength(securityAttributes.SecurityDescriptor)
- if securityAttributes.Length == 0 {
- windows.LocalFree(windows.Handle(securityAttributes.SecurityDescriptor))
+ var ace uintptr
+ for i := uint32(0); i < daclInfo.aceCount; i++ {
+ err = getAce(uintptr(unsafe.Pointer(&dacl[0])), i, &ace)
+ if err != nil {
+ return nil, err
+ }
+ err = addAce(uintptr(unsafe.Pointer(&newDacl[0])), ACL_REVISION, ^uint32(0), ace, uint32(((*ACE_HEADER)(unsafe.Pointer(ace))).aceSize))
+ if err != nil {
+ return nil, err
+ }
+ }
+ runtime.KeepAlive(dacl)
+ err = addAccessAllowedAce(uintptr(unsafe.Pointer(&newDacl[0])), ACL_REVISION, PROCESS_QUERY_LIMITED_INFORMATION, logonSid)
+ if err != nil {
return nil, err
}
- return securityAttributes, nil
+ runtime.KeepAlive(gs)
+ err = setSecurityDescriptorDacl(uintptr(unsafe.Pointer(&absoluteSecurityDescriptor[0])), true, uintptr(unsafe.Pointer(&newDacl[0])), false)
+ if err != nil {
+ return nil, err
+ }
+ //TODO: This should not be required!! But right now we can't give the process the high integrity SACL, which is unfortunate. So we unset it.
+ err = setSecurityDescriptorSacl(uintptr(unsafe.Pointer(&absoluteSecurityDescriptor[0])), false, 0, true)
+ if err != nil {
+ return nil, err
+ }
+ var selfRelativeSecurityDescriptorSize uint32
+ err = makeSelfRelativeSd(uintptr(unsafe.Pointer(&absoluteSecurityDescriptor[0])), 0, &selfRelativeSecurityDescriptorSize)
+ if err != windows.ERROR_INSUFFICIENT_BUFFER {
+ return nil, fmt.Errorf("Expected insufficient buffer from MakeSelfRelativeSd, but got: %v", err)
+ }
+ relativeSecurityDescriptor := make([]byte, selfRelativeSecurityDescriptorSize)
+ err = makeSelfRelativeSd(uintptr(unsafe.Pointer(&absoluteSecurityDescriptor[0])), uintptr(unsafe.Pointer(&relativeSecurityDescriptor[0])), &selfRelativeSecurityDescriptorSize)
+ if err != nil {
+ return nil, err
+ }
+ runtime.KeepAlive(absoluteSecurityDescriptor)
+ runtime.KeepAlive(newDacl)
+ runtime.KeepAlive(sacl)
+ runtime.KeepAlive(owner)
+ runtime.KeepAlive(primaryGroup)
+
+ return relativeSecurityDescriptor, nil
}
diff --git a/service/service_manager.go b/service/service_manager.go
index aae11daf..2862c729 100644
--- a/service/service_manager.go
+++ b/service/service_manager.go
@@ -54,12 +54,6 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
serviceError = ErrorDetermineExecutablePath
return
}
- securityAttributes, err := getCurrentSecurityAttributes()
- if err != nil {
- serviceError = ErrorCreateSecurityDescriptor
- return
- }
- defer windows.LocalFree(windows.Handle(securityAttributes.SecurityDescriptor))
devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
if err != nil {
@@ -124,6 +118,11 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
log.Printf("Unable to determine elevated environment: %v", err)
return
}
+ securityAttributes, err := getSecurityAttributes(userTokenInfo.elevatedToken, userToken)
+ if err != nil {
+ log.Printf("Unable to extract security attributes from elevated token and combine them with SID from user token: %v", err)
+ return
+ }
for {
if stoppingManager {
return
@@ -153,19 +152,9 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
log.Printf("Starting UI process for user: '%s@%s'", username, domain)
attr := &os.ProcAttr{
Sys: &syscall.SysProcAttr{
- Token: syscall.Token(userToken),
-
- /* TODO: XXX: BUG: HACK: DO NOT SHIP WITH THIS COMMENT:
- * These next two lines are commented out, because:
- * - We're uncertain of their correctness, especially with regards to integrity level.
- * - The permissions are too tight and they interfere with some UI things like notification
- * balloon icons.
- * These will be reenabled once we've figured out the right way to do it, and this
- * program should not ship until we've done so.
-
- ProcessAttributes: &securityAttributes,
- ThreadAttributes: &securityAttributes,
- */
+ Token: syscall.Token(userToken),
+ ProcessAttributes: sliceToSecurityAttributes(securityAttributes),
+ ThreadAttributes: sliceToSecurityAttributes(securityAttributes),
},
Files: []*os.File{devNull, devNull, devNull},
Env: env,
diff --git a/service/zsyscall_windows.go b/service/zsyscall_windows.go
index 6005e2d9..fca55092 100644
--- a/service/zsyscall_windows.go
+++ b/service/zsyscall_windows.go
@@ -47,6 +47,15 @@ var (
procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory")
procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo")
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
+ procAddAccessAllowedAce = modadvapi32.NewProc("AddAccessAllowedAce")
+ procSetSecurityDescriptorDacl = modadvapi32.NewProc("SetSecurityDescriptorDacl")
+ procSetSecurityDescriptorSacl = modadvapi32.NewProc("SetSecurityDescriptorSacl")
+ procGetAclInformation = modadvapi32.NewProc("GetAclInformation")
+ procGetAce = modadvapi32.NewProc("GetAce")
+ procAddAce = modadvapi32.NewProc("AddAce")
+ procInitializeAcl = modadvapi32.NewProc("InitializeAcl")
+ procMakeAbsoluteSD = modadvapi32.NewProc("MakeAbsoluteSD")
+ procMakeSelfRelativeSD = modadvapi32.NewProc("MakeSelfRelativeSD")
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW")
@@ -82,8 +91,8 @@ func wtsFreeMemory(ptr uintptr) {
return
}
-func getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) {
- r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(sidOwner)), uintptr(unsafe.Pointer(sidGroup)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(securityDescriptor)), 0)
+func getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, owner *uintptr, group *uintptr, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(securityDescriptor)), 0)
if r1 != 0 {
if e1 != 0 {
err = errnoErr(e1)
@@ -100,6 +109,138 @@ func getSecurityDescriptorLength(securityDescriptor uintptr) (len uint32) {
return
}
+func addAccessAllowedAce(acl uintptr, aceRevision uint32, accessmask uint32, sid *windows.SID) (err error) {
+ r1, _, e1 := syscall.Syscall6(procAddAccessAllowedAce.Addr(), 4, uintptr(acl), uintptr(aceRevision), uintptr(accessmask), uintptr(unsafe.Pointer(sid)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func setSecurityDescriptorDacl(securityDescriptor uintptr, daclPresent bool, dacl uintptr, defaulted bool) (err error) {
+ var _p0 uint32
+ if daclPresent {
+ _p0 = 1
+ } else {
+ _p0 = 0
+ }
+ var _p1 uint32
+ if defaulted {
+ _p1 = 1
+ } else {
+ _p1 = 0
+ }
+ r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorDacl.Addr(), 4, uintptr(securityDescriptor), uintptr(_p0), uintptr(dacl), uintptr(_p1), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func setSecurityDescriptorSacl(securityDescriptor uintptr, saclPresent bool, sacl uintptr, defaulted bool) (err error) {
+ var _p0 uint32
+ if saclPresent {
+ _p0 = 1
+ } else {
+ _p0 = 0
+ }
+ var _p1 uint32
+ if defaulted {
+ _p1 = 1
+ } else {
+ _p1 = 0
+ }
+ r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorSacl.Addr(), 4, uintptr(securityDescriptor), uintptr(_p0), uintptr(sacl), uintptr(_p1), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func getAclInformation(acl uintptr, info unsafe.Pointer, len uint32, infoclass uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetAclInformation.Addr(), 4, uintptr(acl), uintptr(info), uintptr(len), uintptr(infoclass), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func getAce(acl uintptr, index uint32, ace *uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(acl), uintptr(index), uintptr(unsafe.Pointer(ace)))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func addAce(acl uintptr, revision uint32, index uint32, ace uintptr, lenAce uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procAddAce.Addr(), 5, uintptr(acl), uintptr(revision), uintptr(index), uintptr(ace), uintptr(lenAce), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func initializeAcl(acl uintptr, len uint32, revision uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procInitializeAcl.Addr(), 3, uintptr(acl), uintptr(len), uintptr(revision))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func makeAbsoluteSd(selfRelativeSecurityDescriptor uintptr, absoluteSecurityDescriptor uintptr, absoluteSecurityDescriptorSize *uint32, dacl uintptr, daclSize *uint32, sacl uintptr, saclSize *uint32, owner uintptr, ownerSize *uint32, primaryGroup uintptr, primaryGroupSize *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall12(procMakeAbsoluteSD.Addr(), 11, uintptr(selfRelativeSecurityDescriptor), uintptr(absoluteSecurityDescriptor), uintptr(unsafe.Pointer(absoluteSecurityDescriptorSize)), uintptr(dacl), uintptr(unsafe.Pointer(daclSize)), uintptr(sacl), uintptr(unsafe.Pointer(saclSize)), uintptr(owner), uintptr(unsafe.Pointer(ownerSize)), uintptr(primaryGroup), uintptr(unsafe.Pointer(primaryGroupSize)), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func makeSelfRelativeSd(absoluteSecurityDescriptor uintptr, relativeSecurityDescriptor uintptr, relativeSecurityDescriptorSize *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procMakeSelfRelativeSD.Addr(), 3, uintptr(absoluteSecurityDescriptor), uintptr(relativeSecurityDescriptor), uintptr(unsafe.Pointer(relativeSecurityDescriptorSize)))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
func createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) {
var _p0 uint32
if inheritExisting {