]> Cypherpunks.ru repositories - gostls13.git/blob - src/syscall/security_windows.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / syscall / security_windows.go
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.
4
5 package syscall
6
7 import (
8         "unsafe"
9 )
10
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
17 )
18
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
30 )
31
32 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
33 // https://learn.microsoft.com/en-gb/archive/blogs/drnick/windows-and-upn-format-credentials
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
36
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
43         }
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
50                 }
51                 if e != ERROR_INSUFFICIENT_BUFFER {
52                         return "", e
53                 }
54                 if n <= uint32(len(b)) {
55                         return "", e
56                 }
57         }
58 }
59
60 const (
61         // do not reorder
62         NetSetupUnknownStatus = iota
63         NetSetupUnjoined
64         NetSetupWorkgroupName
65         NetSetupDomainName
66 )
67
68 type UserInfo10 struct {
69         Name       *uint16
70         Comment    *uint16
71         UsrComment *uint16
72         FullName   *uint16
73 }
74
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
78
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
91 )
92
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
99
100 // The security identifier (SID) structure is a variable-length
101 // structure used to uniquely identify users or groups.
102 type SID struct{}
103
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
111         }
112         e = ConvertStringSidToSid(p, &sid)
113         if e != nil {
114                 return nil, e
115         }
116         defer LocalFree((Handle)(unsafe.Pointer(sid)))
117         return sid.Copy()
118 }
119
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
126         }
127         acc, e := UTF16PtrFromString(account)
128         if e != nil {
129                 return nil, "", 0, e
130         }
131         var sys *uint16
132         if len(system) > 0 {
133                 sys, e = UTF16PtrFromString(system)
134                 if e != nil {
135                         return nil, "", 0, e
136                 }
137         }
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
147                 }
148                 if e != ERROR_INSUFFICIENT_BUFFER {
149                         return nil, "", 0, e
150                 }
151                 if n <= uint32(len(b)) {
152                         return nil, "", 0, e
153                 }
154         }
155 }
156
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
164         }
165         defer LocalFree((Handle)(unsafe.Pointer(s)))
166         return utf16PtrToString(s), nil
167 }
168
169 // Len returns the length, in bytes, of a valid security identifier sid.
170 func (sid *SID) Len() int {
171         return int(GetLengthSid(sid))
172 }
173
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
181         }
182         return sid2, nil
183 }
184
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
194                 }
195         }
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
204                 }
205                 if e != ERROR_INSUFFICIENT_BUFFER {
206                         return "", "", 0, e
207                 }
208                 if n <= uint32(len(b)) {
209                         return "", "", 0, e
210                 }
211         }
212 }
213
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
225
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
242 )
243
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
275 )
276
277 type SIDAndAttributes struct {
278         Sid        *SID
279         Attributes uint32
280 }
281
282 type Tokenuser struct {
283         User SIDAndAttributes
284 }
285
286 type Tokenprimarygroup struct {
287         PrimaryGroup *SID
288 }
289
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
294 // An access token contains the security information for a logon session.
295 // The system creates an access token when a user logs on, and every
296 // process executed on behalf of the user has a copy of the token.
297 // The token identifies the user, the user's groups, and the user's
298 // privileges. The system uses the token to control access to securable
299 // objects and to control the ability of the user to perform various
300 // system-related operations on the local computer.
301 type Token Handle
302
303 // OpenCurrentProcessToken opens the access token
304 // associated with current process.
305 func OpenCurrentProcessToken() (Token, error) {
306         p, e := GetCurrentProcess()
307         if e != nil {
308                 return 0, e
309         }
310         var t Token
311         e = OpenProcessToken(p, TOKEN_QUERY, &t)
312         if e != nil {
313                 return 0, e
314         }
315         return t, nil
316 }
317
318 // Close releases access to access token.
319 func (t Token) Close() error {
320         return CloseHandle(Handle(t))
321 }
322
323 // getInfo retrieves a specified type of information about an access token.
324 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
325         n := uint32(initSize)
326         for {
327                 b := make([]byte, n)
328                 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
329                 if e == nil {
330                         return unsafe.Pointer(&b[0]), nil
331                 }
332                 if e != ERROR_INSUFFICIENT_BUFFER {
333                         return nil, e
334                 }
335                 if n <= uint32(len(b)) {
336                         return nil, e
337                 }
338         }
339 }
340
341 // GetTokenUser retrieves access token t user account information.
342 func (t Token) GetTokenUser() (*Tokenuser, error) {
343         i, e := t.getInfo(TokenUser, 50)
344         if e != nil {
345                 return nil, e
346         }
347         return (*Tokenuser)(i), nil
348 }
349
350 // GetTokenPrimaryGroup retrieves access token t primary group information.
351 // A pointer to a SID structure representing a group that will become
352 // the primary group of any objects created by a process using this access token.
353 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
354         i, e := t.getInfo(TokenPrimaryGroup, 50)
355         if e != nil {
356                 return nil, e
357         }
358         return (*Tokenprimarygroup)(i), nil
359 }
360
361 // GetUserProfileDirectory retrieves path to the
362 // root directory of the access token t user's profile.
363 func (t Token) GetUserProfileDirectory() (string, error) {
364         n := uint32(100)
365         for {
366                 b := make([]uint16, n)
367                 e := GetUserProfileDirectory(t, &b[0], &n)
368                 if e == nil {
369                         return UTF16ToString(b), nil
370                 }
371                 if e != ERROR_INSUFFICIENT_BUFFER {
372                         return "", e
373                 }
374                 if n <= uint32(len(b)) {
375                         return "", e
376                 }
377         }
378 }