1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package windows
6
7import (
8	"syscall"
9)
10
11const (
12	SecurityAnonymous      = 0
13	SecurityIdentification = 1
14	SecurityImpersonation  = 2
15	SecurityDelegation     = 3
16)
17
18//sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
19//sys	RevertToSelf() (err error) = advapi32.RevertToSelf
20
21const (
22	TOKEN_ADJUST_PRIVILEGES = 0x0020
23	SE_PRIVILEGE_ENABLED    = 0x00000002
24)
25
26type LUID struct {
27	LowPart  uint32
28	HighPart int32
29}
30
31type LUID_AND_ATTRIBUTES struct {
32	Luid       LUID
33	Attributes uint32
34}
35
36type TOKEN_PRIVILEGES struct {
37	PrivilegeCount uint32
38	Privileges     [1]LUID_AND_ATTRIBUTES
39}
40
41//sys	OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) = advapi32.OpenThreadToken
42//sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
43//sys	adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) [true] = advapi32.AdjustTokenPrivileges
44
45func AdjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) error {
46	ret, err := adjustTokenPrivileges(token, disableAllPrivileges, newstate, buflen, prevstate, returnlen)
47	if ret == 0 {
48		// AdjustTokenPrivileges call failed
49		return err
50	}
51	// AdjustTokenPrivileges call succeeded
52	if err == syscall.EINVAL {
53		// GetLastError returned ERROR_SUCCESS
54		return nil
55	}
56	return err
57}
58