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
85//sys	GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) = userenv.GetProfilesDirectoryW
86
87const (
88	LG_INCLUDE_INDIRECT  = 0x1
89	MAX_PREFERRED_LENGTH = 0xFFFFFFFF
90)
91
92type LocalGroupUserInfo0 struct {
93	Name *uint16
94}
95
96type UserInfo4 struct {
97	Name            *uint16
98	Password        *uint16
99	PasswordAge     uint32
100	Priv            uint32
101	HomeDir         *uint16
102	Comment         *uint16
103	Flags           uint32
104	ScriptPath      *uint16
105	AuthFlags       uint32
106	FullName        *uint16
107	UsrComment      *uint16
108	Parms           *uint16
109	Workstations    *uint16
110	LastLogon       uint32
111	LastLogoff      uint32
112	AcctExpires     uint32
113	MaxStorage      uint32
114	UnitsPerWeek    uint32
115	LogonHours      *byte
116	BadPwCount      uint32
117	NumLogons       uint32
118	LogonServer     *uint16
119	CountryCode     uint32
120	CodePage        uint32
121	UserSid         *syscall.SID
122	PrimaryGroupID  uint32
123	Profile         *uint16
124	HomeDirDrive    *uint16
125	PasswordExpired uint32
126}
127
128//sys	NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) = netapi32.NetUserGetLocalGroups
129