golang.zx2c4.com/wireguard/windows@v0.5.4-0.20230123132234-dcc0eb72a04b/elevate/privileges.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package elevate 7 8 import ( 9 "errors" 10 "runtime" 11 "unsafe" 12 13 "golang.org/x/sys/windows" 14 ) 15 16 func DropAllPrivileges(retainDriverLoading bool) error { 17 var luid windows.LUID 18 if retainDriverLoading { 19 err := windows.LookupPrivilegeValue(nil, windows.StringToUTF16Ptr("SeLoadDriverPrivilege"), &luid) 20 if err != nil { 21 return err 22 } 23 } 24 var processToken windows.Token 25 err := windows.OpenProcessToken(windows.CurrentProcess(), windows.TOKEN_READ|windows.TOKEN_WRITE, &processToken) 26 if err != nil { 27 return err 28 } 29 defer processToken.Close() 30 31 var bufferSizeRequired uint32 32 windows.GetTokenInformation(processToken, windows.TokenPrivileges, nil, 0, &bufferSizeRequired) 33 if bufferSizeRequired == 0 || bufferSizeRequired < uint32(unsafe.Sizeof(windows.Tokenprivileges{}.PrivilegeCount)) { 34 return errors.New("GetTokenInformation failed to provide a buffer size") 35 } 36 buffer := make([]byte, bufferSizeRequired) 37 var bytesWritten uint32 38 err = windows.GetTokenInformation(processToken, windows.TokenPrivileges, &buffer[0], uint32(len(buffer)), &bytesWritten) 39 if err != nil { 40 return err 41 } 42 if bytesWritten != bufferSizeRequired { 43 return errors.New("GetTokenInformation returned incomplete data") 44 } 45 tokenPrivileges := (*windows.Tokenprivileges)(unsafe.Pointer(&buffer[0])) 46 for i := uint32(0); i < tokenPrivileges.PrivilegeCount; i++ { 47 item := (*windows.LUIDAndAttributes)(unsafe.Add(unsafe.Pointer(&tokenPrivileges.Privileges[0]), unsafe.Sizeof(tokenPrivileges.Privileges[0])*uintptr(i))) 48 if retainDriverLoading && item.Luid == luid { 49 continue 50 } 51 item.Attributes = windows.SE_PRIVILEGE_REMOVED 52 } 53 err = windows.AdjustTokenPrivileges(processToken, false, tokenPrivileges, 0, nil, nil) 54 runtime.KeepAlive(buffer) 55 return err 56 }