OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / sys / windows / 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 windows
6
7 import (
8         "syscall"
9         "unsafe"
10 )
11
12 const (
13         STANDARD_RIGHTS_REQUIRED = 0xf0000
14         STANDARD_RIGHTS_READ     = 0x20000
15         STANDARD_RIGHTS_WRITE    = 0x20000
16         STANDARD_RIGHTS_EXECUTE  = 0x20000
17         STANDARD_RIGHTS_ALL      = 0x1F0000
18 )
19
20 const (
21         NameUnknown          = 0
22         NameFullyQualifiedDN = 1
23         NameSamCompatible    = 2
24         NameDisplay          = 3
25         NameUniqueId         = 6
26         NameCanonical        = 7
27         NameUserPrincipal    = 8
28         NameCanonicalEx      = 9
29         NameServicePrincipal = 10
30         NameDnsDomain        = 12
31 )
32
33 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
34 // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
35 //sys   TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
36 //sys   GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
37
38 // TranslateAccountName converts a directory service
39 // object name from one format to another.
40 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
41         u, e := UTF16PtrFromString(username)
42         if e != nil {
43                 return "", e
44         }
45         n := uint32(50)
46         for {
47                 b := make([]uint16, n)
48                 e = TranslateName(u, from, to, &b[0], &n)
49                 if e == nil {
50                         return UTF16ToString(b[:n]), nil
51                 }
52                 if e != ERROR_INSUFFICIENT_BUFFER {
53                         return "", e
54                 }
55                 if n <= uint32(len(b)) {
56                         return "", e
57                 }
58         }
59 }
60
61 const (
62         // do not reorder
63         NetSetupUnknownStatus = iota
64         NetSetupUnjoined
65         NetSetupWorkgroupName
66         NetSetupDomainName
67 )
68
69 type UserInfo10 struct {
70         Name       *uint16
71         Comment    *uint16
72         UsrComment *uint16
73         FullName   *uint16
74 }
75
76 //sys   NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
77 //sys   NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
78 //sys   NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
79
80 const (
81         // do not reorder
82         SidTypeUser = 1 + iota
83         SidTypeGroup
84         SidTypeDomain
85         SidTypeAlias
86         SidTypeWellKnownGroup
87         SidTypeDeletedAccount
88         SidTypeInvalid
89         SidTypeUnknown
90         SidTypeComputer
91         SidTypeLabel
92 )
93
94 type SidIdentifierAuthority struct {
95         Value [6]byte
96 }
97
98 var (
99         SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
100         SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
101         SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
102         SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
103         SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
104         SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
105         SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
106 )
107
108 const (
109         SECURITY_NULL_RID                   = 0
110         SECURITY_WORLD_RID                  = 0
111         SECURITY_LOCAL_RID                  = 0
112         SECURITY_CREATOR_OWNER_RID          = 0
113         SECURITY_CREATOR_GROUP_RID          = 1
114         SECURITY_DIALUP_RID                 = 1
115         SECURITY_NETWORK_RID                = 2
116         SECURITY_BATCH_RID                  = 3
117         SECURITY_INTERACTIVE_RID            = 4
118         SECURITY_LOGON_IDS_RID              = 5
119         SECURITY_SERVICE_RID                = 6
120         SECURITY_LOCAL_SYSTEM_RID           = 18
121         SECURITY_BUILTIN_DOMAIN_RID         = 32
122         SECURITY_PRINCIPAL_SELF_RID         = 10
123         SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
124         SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
125         SECURITY_LOGON_IDS_RID_COUNT        = 0x3
126         SECURITY_ANONYMOUS_LOGON_RID        = 0x7
127         SECURITY_PROXY_RID                  = 0x8
128         SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
129         SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
130         SECURITY_AUTHENTICATED_USER_RID     = 0xb
131         SECURITY_RESTRICTED_CODE_RID        = 0xc
132         SECURITY_NT_NON_UNIQUE_RID          = 0x15
133 )
134
135 //sys   LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
136 //sys   LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
137 //sys   ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
138 //sys   ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
139 //sys   GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
140 //sys   CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
141 //sys   AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
142 //sys   FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
143 //sys   EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
144
145 // The security identifier (SID) structure is a variable-length
146 // structure used to uniquely identify users or groups.
147 type SID struct{}
148
149 // StringToSid converts a string-format security identifier
150 // sid into a valid, functional sid.
151 func StringToSid(s string) (*SID, error) {
152         var sid *SID
153         p, e := UTF16PtrFromString(s)
154         if e != nil {
155                 return nil, e
156         }
157         e = ConvertStringSidToSid(p, &sid)
158         if e != nil {
159                 return nil, e
160         }
161         defer LocalFree((Handle)(unsafe.Pointer(sid)))
162         return sid.Copy()
163 }
164
165 // LookupSID retrieves a security identifier sid for the account
166 // and the name of the domain on which the account was found.
167 // System specify target computer to search.
168 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
169         if len(account) == 0 {
170                 return nil, "", 0, syscall.EINVAL
171         }
172         acc, e := UTF16PtrFromString(account)
173         if e != nil {
174                 return nil, "", 0, e
175         }
176         var sys *uint16
177         if len(system) > 0 {
178                 sys, e = UTF16PtrFromString(system)
179                 if e != nil {
180                         return nil, "", 0, e
181                 }
182         }
183         n := uint32(50)
184         dn := uint32(50)
185         for {
186                 b := make([]byte, n)
187                 db := make([]uint16, dn)
188                 sid = (*SID)(unsafe.Pointer(&b[0]))
189                 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
190                 if e == nil {
191                         return sid, UTF16ToString(db), accType, nil
192                 }
193                 if e != ERROR_INSUFFICIENT_BUFFER {
194                         return nil, "", 0, e
195                 }
196                 if n <= uint32(len(b)) {
197                         return nil, "", 0, e
198                 }
199         }
200 }
201
202 // String converts sid to a string format
203 // suitable for display, storage, or transmission.
204 func (sid *SID) String() (string, error) {
205         var s *uint16
206         e := ConvertSidToStringSid(sid, &s)
207         if e != nil {
208                 return "", e
209         }
210         defer LocalFree((Handle)(unsafe.Pointer(s)))
211         return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
212 }
213
214 // Len returns the length, in bytes, of a valid security identifier sid.
215 func (sid *SID) Len() int {
216         return int(GetLengthSid(sid))
217 }
218
219 // Copy creates a duplicate of security identifier sid.
220 func (sid *SID) Copy() (*SID, error) {
221         b := make([]byte, sid.Len())
222         sid2 := (*SID)(unsafe.Pointer(&b[0]))
223         e := CopySid(uint32(len(b)), sid2, sid)
224         if e != nil {
225                 return nil, e
226         }
227         return sid2, nil
228 }
229
230 // LookupAccount retrieves the name of the account for this sid
231 // and the name of the first domain on which this sid is found.
232 // System specify target computer to search for.
233 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
234         var sys *uint16
235         if len(system) > 0 {
236                 sys, err = UTF16PtrFromString(system)
237                 if err != nil {
238                         return "", "", 0, err
239                 }
240         }
241         n := uint32(50)
242         dn := uint32(50)
243         for {
244                 b := make([]uint16, n)
245                 db := make([]uint16, dn)
246                 e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
247                 if e == nil {
248                         return UTF16ToString(b), UTF16ToString(db), accType, nil
249                 }
250                 if e != ERROR_INSUFFICIENT_BUFFER {
251                         return "", "", 0, e
252                 }
253                 if n <= uint32(len(b)) {
254                         return "", "", 0, e
255                 }
256         }
257 }
258
259 const (
260         // do not reorder
261         TOKEN_ASSIGN_PRIMARY = 1 << iota
262         TOKEN_DUPLICATE
263         TOKEN_IMPERSONATE
264         TOKEN_QUERY
265         TOKEN_QUERY_SOURCE
266         TOKEN_ADJUST_PRIVILEGES
267         TOKEN_ADJUST_GROUPS
268         TOKEN_ADJUST_DEFAULT
269
270         TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
271                 TOKEN_ASSIGN_PRIMARY |
272                 TOKEN_DUPLICATE |
273                 TOKEN_IMPERSONATE |
274                 TOKEN_QUERY |
275                 TOKEN_QUERY_SOURCE |
276                 TOKEN_ADJUST_PRIVILEGES |
277                 TOKEN_ADJUST_GROUPS |
278                 TOKEN_ADJUST_DEFAULT
279         TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
280         TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
281                 TOKEN_ADJUST_PRIVILEGES |
282                 TOKEN_ADJUST_GROUPS |
283                 TOKEN_ADJUST_DEFAULT
284         TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
285 )
286
287 const (
288         // do not reorder
289         TokenUser = 1 + iota
290         TokenGroups
291         TokenPrivileges
292         TokenOwner
293         TokenPrimaryGroup
294         TokenDefaultDacl
295         TokenSource
296         TokenType
297         TokenImpersonationLevel
298         TokenStatistics
299         TokenRestrictedSids
300         TokenSessionId
301         TokenGroupsAndPrivileges
302         TokenSessionReference
303         TokenSandBoxInert
304         TokenAuditPolicy
305         TokenOrigin
306         TokenElevationType
307         TokenLinkedToken
308         TokenElevation
309         TokenHasRestrictions
310         TokenAccessInformation
311         TokenVirtualizationAllowed
312         TokenVirtualizationEnabled
313         TokenIntegrityLevel
314         TokenUIAccess
315         TokenMandatoryPolicy
316         TokenLogonSid
317         MaxTokenInfoClass
318 )
319
320 type SIDAndAttributes struct {
321         Sid        *SID
322         Attributes uint32
323 }
324
325 type Tokenuser struct {
326         User SIDAndAttributes
327 }
328
329 type Tokenprimarygroup struct {
330         PrimaryGroup *SID
331 }
332
333 type Tokengroups struct {
334         GroupCount uint32
335         Groups     [1]SIDAndAttributes
336 }
337
338 //sys   OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
339 //sys   GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
340 //sys   GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
341
342 // An access token contains the security information for a logon session.
343 // The system creates an access token when a user logs on, and every
344 // process executed on behalf of the user has a copy of the token.
345 // The token identifies the user, the user's groups, and the user's
346 // privileges. The system uses the token to control access to securable
347 // objects and to control the ability of the user to perform various
348 // system-related operations on the local computer.
349 type Token Handle
350
351 // OpenCurrentProcessToken opens the access token
352 // associated with current process.
353 func OpenCurrentProcessToken() (Token, error) {
354         p, e := GetCurrentProcess()
355         if e != nil {
356                 return 0, e
357         }
358         var t Token
359         e = OpenProcessToken(p, TOKEN_QUERY, &t)
360         if e != nil {
361                 return 0, e
362         }
363         return t, nil
364 }
365
366 // Close releases access to access token.
367 func (t Token) Close() error {
368         return CloseHandle(Handle(t))
369 }
370
371 // getInfo retrieves a specified type of information about an access token.
372 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
373         n := uint32(initSize)
374         for {
375                 b := make([]byte, n)
376                 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
377                 if e == nil {
378                         return unsafe.Pointer(&b[0]), nil
379                 }
380                 if e != ERROR_INSUFFICIENT_BUFFER {
381                         return nil, e
382                 }
383                 if n <= uint32(len(b)) {
384                         return nil, e
385                 }
386         }
387 }
388
389 // GetTokenUser retrieves access token t user account information.
390 func (t Token) GetTokenUser() (*Tokenuser, error) {
391         i, e := t.getInfo(TokenUser, 50)
392         if e != nil {
393                 return nil, e
394         }
395         return (*Tokenuser)(i), nil
396 }
397
398 // GetTokenGroups retrieves group accounts associated with access token t.
399 func (t Token) GetTokenGroups() (*Tokengroups, error) {
400         i, e := t.getInfo(TokenGroups, 50)
401         if e != nil {
402                 return nil, e
403         }
404         return (*Tokengroups)(i), nil
405 }
406
407 // GetTokenPrimaryGroup retrieves access token t primary group information.
408 // A pointer to a SID structure representing a group that will become
409 // the primary group of any objects created by a process using this access token.
410 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
411         i, e := t.getInfo(TokenPrimaryGroup, 50)
412         if e != nil {
413                 return nil, e
414         }
415         return (*Tokenprimarygroup)(i), nil
416 }
417
418 // GetUserProfileDirectory retrieves path to the
419 // root directory of the access token t user's profile.
420 func (t Token) GetUserProfileDirectory() (string, error) {
421         n := uint32(100)
422         for {
423                 b := make([]uint16, n)
424                 e := GetUserProfileDirectory(t, &b[0], &n)
425                 if e == nil {
426                         return UTF16ToString(b), nil
427                 }
428                 if e != ERROR_INSUFFICIENT_BUFFER {
429                         return "", e
430                 }
431                 if n <= uint32(len(b)) {
432                         return "", e
433                 }
434         }
435 }