Fix "PR c++/92804 ICE trying to use concept as a nested-name-specifier"
[official-gcc.git] / libgo / go / syscall / security_windows.go
blob3a757596066b3b67e6535b78254393f7c7c14696
1 // Copyright 2012 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.
5 package syscall
7 import (
8 "unsafe"
11 const (
12 STANDARD_RIGHTS_REQUIRED = 0xf0000
13 STANDARD_RIGHTS_READ = 0x20000
14 STANDARD_RIGHTS_WRITE = 0x20000
15 STANDARD_RIGHTS_EXECUTE = 0x20000
16 STANDARD_RIGHTS_ALL = 0x1F0000
19 const (
20 NameUnknown = 0
21 NameFullyQualifiedDN = 1
22 NameSamCompatible = 2
23 NameDisplay = 3
24 NameUniqueId = 6
25 NameCanonical = 7
26 NameUserPrincipal = 8
27 NameCanonicalEx = 9
28 NameServicePrincipal = 10
29 NameDnsDomain = 12
32 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
33 // https://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
34 //sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
35 //sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
37 // TranslateAccountName converts a directory service
38 // object name from one format to another.
39 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
40 u, e := UTF16PtrFromString(username)
41 if e != nil {
42 return "", e
44 n := uint32(50)
45 for {
46 b := make([]uint16, n)
47 e = TranslateName(u, from, to, &b[0], &n)
48 if e == nil {
49 return UTF16ToString(b[:n]), nil
51 if e != ERROR_INSUFFICIENT_BUFFER {
52 return "", e
54 if n <= uint32(len(b)) {
55 return "", e
60 const (
61 // do not reorder
62 NetSetupUnknownStatus = iota
63 NetSetupUnjoined
64 NetSetupWorkgroupName
65 NetSetupDomainName
68 type UserInfo10 struct {
69 Name *uint16
70 Comment *uint16
71 UsrComment *uint16
72 FullName *uint16
75 //sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
76 //sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
77 //sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
79 const (
80 // do not reorder
81 SidTypeUser = 1 + iota
82 SidTypeGroup
83 SidTypeDomain
84 SidTypeAlias
85 SidTypeWellKnownGroup
86 SidTypeDeletedAccount
87 SidTypeInvalid
88 SidTypeUnknown
89 SidTypeComputer
90 SidTypeLabel
93 //sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
94 //sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
95 //sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
96 //sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
97 //sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
98 //sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
100 // The security identifier (SID) structure is a variable-length
101 // structure used to uniquely identify users or groups.
102 type SID struct{}
104 // StringToSid converts a string-format security identifier
105 // sid into a valid, functional sid.
106 func StringToSid(s string) (*SID, error) {
107 var sid *SID
108 p, e := UTF16PtrFromString(s)
109 if e != nil {
110 return nil, e
112 e = ConvertStringSidToSid(p, &sid)
113 if e != nil {
114 return nil, e
116 defer LocalFree((Handle)(unsafe.Pointer(sid)))
117 return sid.Copy()
120 // LookupSID retrieves a security identifier sid for the account
121 // and the name of the domain on which the account was found.
122 // System specify target computer to search.
123 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
124 if len(account) == 0 {
125 return nil, "", 0, EINVAL
127 acc, e := UTF16PtrFromString(account)
128 if e != nil {
129 return nil, "", 0, e
131 var sys *uint16
132 if len(system) > 0 {
133 sys, e = UTF16PtrFromString(system)
134 if e != nil {
135 return nil, "", 0, e
138 n := uint32(50)
139 dn := uint32(50)
140 for {
141 b := make([]byte, n)
142 db := make([]uint16, dn)
143 sid = (*SID)(unsafe.Pointer(&b[0]))
144 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
145 if e == nil {
146 return sid, UTF16ToString(db), accType, nil
148 if e != ERROR_INSUFFICIENT_BUFFER {
149 return nil, "", 0, e
151 if n <= uint32(len(b)) {
152 return nil, "", 0, e
157 // String converts sid to a string format
158 // suitable for display, storage, or transmission.
159 func (sid *SID) String() (string, error) {
160 var s *uint16
161 e := ConvertSidToStringSid(sid, &s)
162 if e != nil {
163 return "", e
165 defer LocalFree((Handle)(unsafe.Pointer(s)))
166 return utf16PtrToString(s, 256), nil
169 // Len returns the length, in bytes, of a valid security identifier sid.
170 func (sid *SID) Len() int {
171 return int(GetLengthSid(sid))
174 // Copy creates a duplicate of security identifier sid.
175 func (sid *SID) Copy() (*SID, error) {
176 b := make([]byte, sid.Len())
177 sid2 := (*SID)(unsafe.Pointer(&b[0]))
178 e := CopySid(uint32(len(b)), sid2, sid)
179 if e != nil {
180 return nil, e
182 return sid2, nil
185 // LookupAccount retrieves the name of the account for this sid
186 // and the name of the first domain on which this sid is found.
187 // System specify target computer to search for.
188 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
189 var sys *uint16
190 if len(system) > 0 {
191 sys, err = UTF16PtrFromString(system)
192 if err != nil {
193 return "", "", 0, err
196 n := uint32(50)
197 dn := uint32(50)
198 for {
199 b := make([]uint16, n)
200 db := make([]uint16, dn)
201 e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
202 if e == nil {
203 return UTF16ToString(b), UTF16ToString(db), accType, nil
205 if e != ERROR_INSUFFICIENT_BUFFER {
206 return "", "", 0, e
208 if n <= uint32(len(b)) {
209 return "", "", 0, e
214 const (
215 // do not reorder
216 TOKEN_ASSIGN_PRIMARY = 1 << iota
217 TOKEN_DUPLICATE
218 TOKEN_IMPERSONATE
219 TOKEN_QUERY
220 TOKEN_QUERY_SOURCE
221 TOKEN_ADJUST_PRIVILEGES
222 TOKEN_ADJUST_GROUPS
223 TOKEN_ADJUST_DEFAULT
224 TOKEN_ADJUST_SESSIONID
226 TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
227 TOKEN_ASSIGN_PRIMARY |
228 TOKEN_DUPLICATE |
229 TOKEN_IMPERSONATE |
230 TOKEN_QUERY |
231 TOKEN_QUERY_SOURCE |
232 TOKEN_ADJUST_PRIVILEGES |
233 TOKEN_ADJUST_GROUPS |
234 TOKEN_ADJUST_DEFAULT |
235 TOKEN_ADJUST_SESSIONID
236 TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
237 TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
238 TOKEN_ADJUST_PRIVILEGES |
239 TOKEN_ADJUST_GROUPS |
240 TOKEN_ADJUST_DEFAULT
241 TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
244 const (
245 // do not reorder
246 TokenUser = 1 + iota
247 TokenGroups
248 TokenPrivileges
249 TokenOwner
250 TokenPrimaryGroup
251 TokenDefaultDacl
252 TokenSource
253 TokenType
254 TokenImpersonationLevel
255 TokenStatistics
256 TokenRestrictedSids
257 TokenSessionId
258 TokenGroupsAndPrivileges
259 TokenSessionReference
260 TokenSandBoxInert
261 TokenAuditPolicy
262 TokenOrigin
263 TokenElevationType
264 TokenLinkedToken
265 TokenElevation
266 TokenHasRestrictions
267 TokenAccessInformation
268 TokenVirtualizationAllowed
269 TokenVirtualizationEnabled
270 TokenIntegrityLevel
271 TokenUIAccess
272 TokenMandatoryPolicy
273 TokenLogonSid
274 MaxTokenInfoClass
277 type SIDAndAttributes struct {
278 Sid *SID
279 Attributes uint32
282 type Tokenuser struct {
283 User SIDAndAttributes
286 type Tokenprimarygroup struct {
287 PrimaryGroup *SID
290 //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
291 //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
292 //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
293 //sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
295 // An access token contains the security information for a logon session.
296 // The system creates an access token when a user logs on, and every
297 // process executed on behalf of the user has a copy of the token.
298 // The token identifies the user, the user's groups, and the user's
299 // privileges. The system uses the token to control access to securable
300 // objects and to control the ability of the user to perform various
301 // system-related operations on the local computer.
302 type Token Handle
304 // OpenCurrentProcessToken opens the access token
305 // associated with current process.
306 func OpenCurrentProcessToken() (Token, error) {
307 p, e := GetCurrentProcess()
308 if e != nil {
309 return 0, e
311 var t Token
312 e = OpenProcessToken(p, TOKEN_QUERY, &t)
313 if e != nil {
314 return 0, e
316 return t, nil
319 // Close releases access to access token.
320 func (t Token) Close() error {
321 return CloseHandle(Handle(t))
324 // getInfo retrieves a specified type of information about an access token.
325 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
326 n := uint32(initSize)
327 for {
328 b := make([]byte, n)
329 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
330 if e == nil {
331 return unsafe.Pointer(&b[0]), nil
333 if e != ERROR_INSUFFICIENT_BUFFER {
334 return nil, e
336 if n <= uint32(len(b)) {
337 return nil, e
342 // GetTokenUser retrieves access token t user account information.
343 func (t Token) GetTokenUser() (*Tokenuser, error) {
344 i, e := t.getInfo(TokenUser, 50)
345 if e != nil {
346 return nil, e
348 return (*Tokenuser)(i), nil
351 // GetTokenPrimaryGroup retrieves access token t primary group information.
352 // A pointer to a SID structure representing a group that will become
353 // the primary group of any objects created by a process using this access token.
354 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
355 i, e := t.getInfo(TokenPrimaryGroup, 50)
356 if e != nil {
357 return nil, e
359 return (*Tokenprimarygroup)(i), nil
362 // GetUserProfileDirectory retrieves path to the
363 // root directory of the access token t user's profile.
364 func (t Token) GetUserProfileDirectory() (string, error) {
365 n := uint32(100)
366 for {
367 b := make([]uint16, n)
368 e := GetUserProfileDirectory(t, &b[0], &n)
369 if e == nil {
370 return UTF16ToString(b), nil
372 if e != ERROR_INSUFFICIENT_BUFFER {
373 return "", e
375 if n <= uint32(len(b)) {
376 return "", e