mirror of
https://github.com/restic/restic.git
synced 2024-12-21 23:33:03 +00:00
Refactor extended attributes and security descriptor helpers to use go-winio (#5040)
* Refactor ea and sd helpers to use go-winio Import go-winio and instead of copying the functions to encode/decode extended attributes and enable process privileges for security descriptors, call the functions defined in go-winio.
This commit is contained in:
parent
d7d9af4c9f
commit
6808004ad1
4 changed files with 23 additions and 389 deletions
1
go.mod
1
go.mod
|
@ -6,6 +6,7 @@ require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0
|
||||||
github.com/Backblaze/blazer v0.7.1
|
github.com/Backblaze/blazer v0.7.1
|
||||||
|
github.com/Microsoft/go-winio v0.6.2
|
||||||
github.com/anacrolix/fuse v0.3.1
|
github.com/anacrolix/fuse v0.3.1
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0
|
github.com/cenkalti/backoff/v4 v4.3.0
|
||||||
github.com/cespare/xxhash/v2 v2.3.0
|
github.com/cespare/xxhash/v2 v2.3.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -33,6 +33,8 @@ github.com/Backblaze/blazer v0.7.1 h1:J43PbFj6hXLg1jvCNr+rQoAsxzKK0IP7ftl1ReCwpc
|
||||||
github.com/Backblaze/blazer v0.7.1/go.mod h1:MhntL1nMpIuoqrPP6TnZu/xTydMgOAe/Xm6KongbjKs=
|
github.com/Backblaze/blazer v0.7.1/go.mod h1:MhntL1nMpIuoqrPP6TnZu/xTydMgOAe/Xm6KongbjKs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/anacrolix/envpprof v1.3.0 h1:WJt9bpuT7A/CDCxPOv/eeZqHWlle/Y0keJUvc6tcJDk=
|
github.com/anacrolix/envpprof v1.3.0 h1:WJt9bpuT7A/CDCxPOv/eeZqHWlle/Y0keJUvc6tcJDk=
|
||||||
github.com/anacrolix/envpprof v1.3.0/go.mod h1:7QIG4CaX1uexQ3tqd5+BRa/9e2D02Wcertl6Yh0jCB0=
|
github.com/anacrolix/envpprof v1.3.0/go.mod h1:7QIG4CaX1uexQ3tqd5+BRa/9e2D02Wcertl6Yh0jCB0=
|
||||||
github.com/anacrolix/fuse v0.3.1 h1:oT8s3B5HFkBdLe/WKJO5MNo9iIyEtc+BhvTZYp4jhDM=
|
github.com/anacrolix/fuse v0.3.1 h1:oT8s3B5HFkBdLe/WKJO5MNo9iIyEtc+BhvTZYp4jhDM=
|
||||||
|
|
|
@ -4,17 +4,28 @@
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The code below was adapted from https://github.com/microsoft/go-winio under MIT license.
|
// extendedAttribute is a type alias for winio.ExtendedAttribute
|
||||||
|
type extendedAttribute = winio.ExtendedAttribute
|
||||||
|
|
||||||
|
// encodeExtendedAttributes encodes the extended attributes to a byte slice.
|
||||||
|
func encodeExtendedAttributes(attrs []extendedAttribute) ([]byte, error) {
|
||||||
|
return winio.EncodeExtendedAttributes(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeExtendedAttributes decodes the extended attributes from a byte slice.
|
||||||
|
func decodeExtendedAttributes(data []byte) ([]extendedAttribute, error) {
|
||||||
|
return winio.DecodeExtendedAttributes(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The code below was copied over from https://github.com/microsoft/go-winio/blob/main/pipe.go under MIT license.
|
||||||
|
|
||||||
// The MIT License (MIT)
|
// The MIT License (MIT)
|
||||||
|
|
||||||
|
@ -38,140 +49,6 @@ import (
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
// The code below was copied over from https://github.com/microsoft/go-winio/blob/main/ea.go under MIT license.
|
|
||||||
|
|
||||||
type fileFullEaInformation struct {
|
|
||||||
NextEntryOffset uint32
|
|
||||||
Flags uint8
|
|
||||||
NameLength uint8
|
|
||||||
ValueLength uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
|
|
||||||
|
|
||||||
errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
|
|
||||||
errEaNameTooLarge = errors.New("extended attribute name too large")
|
|
||||||
errEaValueTooLarge = errors.New("extended attribute value too large")
|
|
||||||
)
|
|
||||||
|
|
||||||
// extendedAttribute represents a single Windows EA.
|
|
||||||
type extendedAttribute struct {
|
|
||||||
Name string
|
|
||||||
Value []byte
|
|
||||||
Flags uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseEa(b []byte) (ea extendedAttribute, nb []byte, err error) {
|
|
||||||
var info fileFullEaInformation
|
|
||||||
err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
|
|
||||||
if err != nil {
|
|
||||||
err = errInvalidEaBuffer
|
|
||||||
return ea, nb, err
|
|
||||||
}
|
|
||||||
|
|
||||||
nameOffset := fileFullEaInformationSize
|
|
||||||
nameLen := int(info.NameLength)
|
|
||||||
valueOffset := nameOffset + int(info.NameLength) + 1
|
|
||||||
valueLen := int(info.ValueLength)
|
|
||||||
nextOffset := int(info.NextEntryOffset)
|
|
||||||
if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
|
|
||||||
err = errInvalidEaBuffer
|
|
||||||
return ea, nb, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ea.Name = string(b[nameOffset : nameOffset+nameLen])
|
|
||||||
ea.Value = b[valueOffset : valueOffset+valueLen]
|
|
||||||
ea.Flags = info.Flags
|
|
||||||
if info.NextEntryOffset != 0 {
|
|
||||||
nb = b[info.NextEntryOffset:]
|
|
||||||
}
|
|
||||||
return ea, nb, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// decodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
|
|
||||||
// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
|
|
||||||
func decodeExtendedAttributes(b []byte) (eas []extendedAttribute, err error) {
|
|
||||||
for len(b) != 0 {
|
|
||||||
ea, nb, err := parseEa(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
eas = append(eas, ea)
|
|
||||||
b = nb
|
|
||||||
}
|
|
||||||
return eas, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeEa(buf *bytes.Buffer, ea *extendedAttribute, last bool) error {
|
|
||||||
if int(uint8(len(ea.Name))) != len(ea.Name) {
|
|
||||||
return errEaNameTooLarge
|
|
||||||
}
|
|
||||||
if int(uint16(len(ea.Value))) != len(ea.Value) {
|
|
||||||
return errEaValueTooLarge
|
|
||||||
}
|
|
||||||
entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
|
|
||||||
withPadding := (entrySize + 3) &^ 3
|
|
||||||
nextOffset := uint32(0)
|
|
||||||
if !last {
|
|
||||||
nextOffset = withPadding
|
|
||||||
}
|
|
||||||
info := fileFullEaInformation{
|
|
||||||
NextEntryOffset: nextOffset,
|
|
||||||
Flags: ea.Flags,
|
|
||||||
NameLength: uint8(len(ea.Name)),
|
|
||||||
ValueLength: uint16(len(ea.Value)),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := binary.Write(buf, binary.LittleEndian, &info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = buf.Write([]byte(ea.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = buf.WriteByte(0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = buf.Write(ea.Value)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
|
|
||||||
// buffer for use with BackupWrite, ZwSetEaFile, etc.
|
|
||||||
func encodeExtendedAttributes(eas []extendedAttribute) ([]byte, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
for i := range eas {
|
|
||||||
last := false
|
|
||||||
if i == len(eas)-1 {
|
|
||||||
last = true
|
|
||||||
}
|
|
||||||
|
|
||||||
err := writeEa(&buf, &eas[i], last)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The code below was copied over from https://github.com/microsoft/go-winio/blob/main/pipe.go under MIT license.
|
|
||||||
|
|
||||||
type ntStatus int32
|
type ntStatus int32
|
||||||
|
|
||||||
func (status ntStatus) Err() error {
|
func (status ntStatus) Err() error {
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio"
|
||||||
"github.com/restic/restic/internal/debug"
|
"github.com/restic/restic/internal/debug"
|
||||||
"github.com/restic/restic/internal/errors"
|
"github.com/restic/restic/internal/errors"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
@ -161,6 +159,10 @@ func setNamedSecurityInfoLow(filePath string, dacl *windows.ACL) error {
|
||||||
return windows.SetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, lowRestoreSecurityFlags, nil, nil, dacl, nil)
|
return windows.SetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, lowRestoreSecurityFlags, nil, nil, dacl, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enableProcessPrivileges(privileges []string) error {
|
||||||
|
return winio.EnableProcessPrivileges(privileges)
|
||||||
|
}
|
||||||
|
|
||||||
// enableBackupPrivilege enables privilege for backing up security descriptors
|
// enableBackupPrivilege enables privilege for backing up security descriptors
|
||||||
func enableBackupPrivilege() {
|
func enableBackupPrivilege() {
|
||||||
err := enableProcessPrivileges([]string{seBackupPrivilege})
|
err := enableProcessPrivileges([]string{seBackupPrivilege})
|
||||||
|
@ -212,251 +214,3 @@ func securityDescriptorStructToBytes(sd *windows.SECURITY_DESCRIPTOR) ([]byte, e
|
||||||
b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length())
|
b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length())
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code below was adapted from
|
|
||||||
// https://github.com/microsoft/go-winio/blob/3c9576c9346a1892dee136329e7e15309e82fb4f/privilege.go
|
|
||||||
// under MIT license.
|
|
||||||
|
|
||||||
// The MIT License (MIT)
|
|
||||||
|
|
||||||
// Copyright (c) 2015 Microsoft
|
|
||||||
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
var (
|
|
||||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
|
||||||
|
|
||||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
|
||||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
|
||||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
|
||||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Do the interface allocations only once for common
|
|
||||||
// Errno values.
|
|
||||||
const (
|
|
||||||
errnoErrorIOPending = 997
|
|
||||||
|
|
||||||
//revive:disable-next-line:var-naming ALL_CAPS
|
|
||||||
SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED
|
|
||||||
|
|
||||||
//revive:disable-next-line:var-naming ALL_CAPS
|
|
||||||
ERROR_NOT_ALL_ASSIGNED windows.Errno = windows.ERROR_NOT_ALL_ASSIGNED
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
errErrorIOPending error = syscall.Errno(errnoErrorIOPending)
|
|
||||||
errErrorEinval error = syscall.EINVAL
|
|
||||||
|
|
||||||
privNames = make(map[string]uint64)
|
|
||||||
privNameMutex sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
// privilegeError represents an error enabling privileges.
|
|
||||||
type privilegeError struct {
|
|
||||||
privileges []uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string message for the error.
|
|
||||||
func (e *privilegeError) Error() string {
|
|
||||||
s := "Could not enable privilege "
|
|
||||||
if len(e.privileges) > 1 {
|
|
||||||
s = "Could not enable privileges "
|
|
||||||
}
|
|
||||||
for i, p := range e.privileges {
|
|
||||||
if i != 0 {
|
|
||||||
s += ", "
|
|
||||||
}
|
|
||||||
s += `"`
|
|
||||||
s += getPrivilegeName(p)
|
|
||||||
s += `"`
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapPrivileges(names []string) ([]uint64, error) {
|
|
||||||
privileges := make([]uint64, 0, len(names))
|
|
||||||
privNameMutex.Lock()
|
|
||||||
defer privNameMutex.Unlock()
|
|
||||||
for _, name := range names {
|
|
||||||
p, ok := privNames[name]
|
|
||||||
if !ok {
|
|
||||||
err := lookupPrivilegeValue("", name, &p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
privNames[name] = p
|
|
||||||
}
|
|
||||||
privileges = append(privileges, p)
|
|
||||||
}
|
|
||||||
return privileges, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// enableProcessPrivileges enables privileges globally for the process.
|
|
||||||
func enableProcessPrivileges(names []string) error {
|
|
||||||
return enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED)
|
|
||||||
}
|
|
||||||
|
|
||||||
func enableDisableProcessPrivilege(names []string, action uint32) error {
|
|
||||||
privileges, err := mapPrivileges(names)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
p := windows.CurrentProcess()
|
|
||||||
var token windows.Token
|
|
||||||
err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_ = token.Close()
|
|
||||||
}()
|
|
||||||
return adjustPrivileges(token, privileges, action)
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {
|
|
||||||
var b bytes.Buffer
|
|
||||||
_ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
|
|
||||||
for _, p := range privileges {
|
|
||||||
_ = binary.Write(&b, binary.LittleEndian, p)
|
|
||||||
_ = binary.Write(&b, binary.LittleEndian, action)
|
|
||||||
}
|
|
||||||
prevState := make([]byte, b.Len())
|
|
||||||
reqSize := uint32(0)
|
|
||||||
success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
|
|
||||||
if !success {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno
|
|
||||||
debug.Log("Not all requested privileges were fully set: %v. AdjustTokenPrivileges returned warning: %v", privileges, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPrivilegeName(luid uint64) string {
|
|
||||||
var nameBuffer [256]uint16
|
|
||||||
bufSize := uint32(len(nameBuffer))
|
|
||||||
err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %d>", luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
var displayNameBuffer [256]uint16
|
|
||||||
displayBufSize := uint32(len(displayNameBuffer))
|
|
||||||
var langID uint32
|
|
||||||
err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %s>", string(utf16.Decode(nameBuffer[:bufSize])))
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// The functions below are copied over from https://github.com/microsoft/go-winio/blob/main/zsyscall_windows.go under MIT license.
|
|
||||||
|
|
||||||
// This windows api always returns an error even in case of success, warnings (partial success) and error cases.
|
|
||||||
//
|
|
||||||
// Full success - When we call this with admin permissions, it returns DNS_ERROR_RCODE_NO_ERROR (0).
|
|
||||||
// This gets translated to errErrorEinval and ultimately in adjustTokenPrivileges, it gets ignored.
|
|
||||||
//
|
|
||||||
// Partial success - If we call this api without admin privileges, privileges related to SACLs do not get set and
|
|
||||||
// though the api returns success, it returns an error - golang.org/x/sys/windows.ERROR_NOT_ALL_ASSIGNED (1300)
|
|
||||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if releaseAll {
|
|
||||||
_p0 = 1
|
|
||||||
}
|
|
||||||
r0, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
|
||||||
success = r0 != 0
|
|
||||||
if true {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageID *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageID *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeDisplayNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageID)))
|
|
||||||
if r1 == 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)))
|
|
||||||
if r1 == 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var _p1 *uint16
|
|
||||||
_p1, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeValue(_p0, _p1, luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
|
||||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
|
||||||
if r1 == 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The code below was copied from https://github.com/microsoft/go-winio/blob/main/tools/mkwinsyscall/mkwinsyscall.go under MIT license.
|
|
||||||
|
|
||||||
// errnoErr returns common boxed Errno values, to prevent
|
|
||||||
// allocations at runtime.
|
|
||||||
func errnoErr(e syscall.Errno) error {
|
|
||||||
switch e {
|
|
||||||
case 0:
|
|
||||||
return errErrorEinval
|
|
||||||
case errnoErrorIOPending:
|
|
||||||
return errErrorIOPending
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue