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	"unsafe"
10)
11
12const (
13	SecurityAnonymous      = 0
14	SecurityIdentification = 1
15	SecurityImpersonation  = 2
16	SecurityDelegation     = 3
17)
18
19//sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
20//sys	RevertToSelf() (err error) = advapi32.RevertToSelf
21
22const (
23	TOKEN_ADJUST_PRIVILEGES = 0x0020
24	SE_PRIVILEGE_ENABLED    = 0x00000002
25)
26
27type LUID struct {
28	LowPart  uint32
29	HighPart int32
30}
31
32type LUID_AND_ATTRIBUTES struct {
33	Luid       LUID
34	Attributes uint32
35}
36
37type TOKEN_PRIVILEGES struct {
38	PrivilegeCount uint32
39	Privileges     [1]LUID_AND_ATTRIBUTES
40}
41
42//sys	OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) = advapi32.OpenThreadToken
43//sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
44//sys	adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) [true] = advapi32.AdjustTokenPrivileges
45
46func AdjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) error {
47	ret, err := adjustTokenPrivileges(token, disableAllPrivileges, newstate, buflen, prevstate, returnlen)
48	if ret == 0 {
49		// AdjustTokenPrivileges call failed
50		return err
51	}
52	// AdjustTokenPrivileges call succeeded
53	if err == syscall.EINVAL {
54		// GetLastError returned ERROR_SUCCESS
55		return nil
56	}
57	return err
58}
59
60//sys DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) = advapi32.DuplicateTokenEx
61//sys SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) = advapi32.SetTokenInformation
62
63type SID_AND_ATTRIBUTES struct {
64	Sid        *syscall.SID
65	Attributes uint32
66}
67
68type TOKEN_MANDATORY_LABEL struct {
69	Label SID_AND_ATTRIBUTES
70}
71
72func (tml *TOKEN_MANDATORY_LABEL) Size() uint32 {
73	return uint32(unsafe.Sizeof(TOKEN_MANDATORY_LABEL{})) + syscall.GetLengthSid(tml.Label.Sid)
74}
75
76const SE_GROUP_INTEGRITY = 0x00000020
77
78type TokenType uint32
79
80const (
81	TokenPrimary       TokenType = 1
82	TokenImpersonation TokenType = 2
83)
84