Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / 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 // Predefined domain-relative RIDs for local groups.
136 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
137 const (
138         DOMAIN_ALIAS_RID_ADMINS                         = 0x220
139         DOMAIN_ALIAS_RID_USERS                          = 0x221
140         DOMAIN_ALIAS_RID_GUESTS                         = 0x222
141         DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
142         DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
143         DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
144         DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
145         DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
146         DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
147         DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
148         DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
149         DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
150         DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
151         DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
152         DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
153         DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
154         DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
155         DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
156         DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
157         DOMAIN_ALIAS_RID_IUSERS                         = 0x238
158         DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
159         DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
160         DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
161         DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
162         DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
163 )
164
165 //sys   LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
166 //sys   LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
167 //sys   ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
168 //sys   ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
169 //sys   GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
170 //sys   CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
171 //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
172 //sys   createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
173 //sys   FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
174 //sys   EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
175
176 // The security identifier (SID) structure is a variable-length
177 // structure used to uniquely identify users or groups.
178 type SID struct{}
179
180 // StringToSid converts a string-format security identifier
181 // sid into a valid, functional sid.
182 func StringToSid(s string) (*SID, error) {
183         var sid *SID
184         p, e := UTF16PtrFromString(s)
185         if e != nil {
186                 return nil, e
187         }
188         e = ConvertStringSidToSid(p, &sid)
189         if e != nil {
190                 return nil, e
191         }
192         defer LocalFree((Handle)(unsafe.Pointer(sid)))
193         return sid.Copy()
194 }
195
196 // LookupSID retrieves a security identifier sid for the account
197 // and the name of the domain on which the account was found.
198 // System specify target computer to search.
199 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
200         if len(account) == 0 {
201                 return nil, "", 0, syscall.EINVAL
202         }
203         acc, e := UTF16PtrFromString(account)
204         if e != nil {
205                 return nil, "", 0, e
206         }
207         var sys *uint16
208         if len(system) > 0 {
209                 sys, e = UTF16PtrFromString(system)
210                 if e != nil {
211                         return nil, "", 0, e
212                 }
213         }
214         n := uint32(50)
215         dn := uint32(50)
216         for {
217                 b := make([]byte, n)
218                 db := make([]uint16, dn)
219                 sid = (*SID)(unsafe.Pointer(&b[0]))
220                 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
221                 if e == nil {
222                         return sid, UTF16ToString(db), accType, nil
223                 }
224                 if e != ERROR_INSUFFICIENT_BUFFER {
225                         return nil, "", 0, e
226                 }
227                 if n <= uint32(len(b)) {
228                         return nil, "", 0, e
229                 }
230         }
231 }
232
233 // String converts sid to a string format
234 // suitable for display, storage, or transmission.
235 func (sid *SID) String() (string, error) {
236         var s *uint16
237         e := ConvertSidToStringSid(sid, &s)
238         if e != nil {
239                 return "", e
240         }
241         defer LocalFree((Handle)(unsafe.Pointer(s)))
242         return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
243 }
244
245 // Len returns the length, in bytes, of a valid security identifier sid.
246 func (sid *SID) Len() int {
247         return int(GetLengthSid(sid))
248 }
249
250 // Copy creates a duplicate of security identifier sid.
251 func (sid *SID) Copy() (*SID, error) {
252         b := make([]byte, sid.Len())
253         sid2 := (*SID)(unsafe.Pointer(&b[0]))
254         e := CopySid(uint32(len(b)), sid2, sid)
255         if e != nil {
256                 return nil, e
257         }
258         return sid2, nil
259 }
260
261 // LookupAccount retrieves the name of the account for this sid
262 // and the name of the first domain on which this sid is found.
263 // System specify target computer to search for.
264 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
265         var sys *uint16
266         if len(system) > 0 {
267                 sys, err = UTF16PtrFromString(system)
268                 if err != nil {
269                         return "", "", 0, err
270                 }
271         }
272         n := uint32(50)
273         dn := uint32(50)
274         for {
275                 b := make([]uint16, n)
276                 db := make([]uint16, dn)
277                 e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
278                 if e == nil {
279                         return UTF16ToString(b), UTF16ToString(db), accType, nil
280                 }
281                 if e != ERROR_INSUFFICIENT_BUFFER {
282                         return "", "", 0, e
283                 }
284                 if n <= uint32(len(b)) {
285                         return "", "", 0, e
286                 }
287         }
288 }
289
290 // Various types of pre-specified sids that can be synthesized at runtime.
291 type WELL_KNOWN_SID_TYPE uint32
292
293 const (
294         WinNullSid                                    = 0
295         WinWorldSid                                   = 1
296         WinLocalSid                                   = 2
297         WinCreatorOwnerSid                            = 3
298         WinCreatorGroupSid                            = 4
299         WinCreatorOwnerServerSid                      = 5
300         WinCreatorGroupServerSid                      = 6
301         WinNtAuthoritySid                             = 7
302         WinDialupSid                                  = 8
303         WinNetworkSid                                 = 9
304         WinBatchSid                                   = 10
305         WinInteractiveSid                             = 11
306         WinServiceSid                                 = 12
307         WinAnonymousSid                               = 13
308         WinProxySid                                   = 14
309         WinEnterpriseControllersSid                   = 15
310         WinSelfSid                                    = 16
311         WinAuthenticatedUserSid                       = 17
312         WinRestrictedCodeSid                          = 18
313         WinTerminalServerSid                          = 19
314         WinRemoteLogonIdSid                           = 20
315         WinLogonIdsSid                                = 21
316         WinLocalSystemSid                             = 22
317         WinLocalServiceSid                            = 23
318         WinNetworkServiceSid                          = 24
319         WinBuiltinDomainSid                           = 25
320         WinBuiltinAdministratorsSid                   = 26
321         WinBuiltinUsersSid                            = 27
322         WinBuiltinGuestsSid                           = 28
323         WinBuiltinPowerUsersSid                       = 29
324         WinBuiltinAccountOperatorsSid                 = 30
325         WinBuiltinSystemOperatorsSid                  = 31
326         WinBuiltinPrintOperatorsSid                   = 32
327         WinBuiltinBackupOperatorsSid                  = 33
328         WinBuiltinReplicatorSid                       = 34
329         WinBuiltinPreWindows2000CompatibleAccessSid   = 35
330         WinBuiltinRemoteDesktopUsersSid               = 36
331         WinBuiltinNetworkConfigurationOperatorsSid    = 37
332         WinAccountAdministratorSid                    = 38
333         WinAccountGuestSid                            = 39
334         WinAccountKrbtgtSid                           = 40
335         WinAccountDomainAdminsSid                     = 41
336         WinAccountDomainUsersSid                      = 42
337         WinAccountDomainGuestsSid                     = 43
338         WinAccountComputersSid                        = 44
339         WinAccountControllersSid                      = 45
340         WinAccountCertAdminsSid                       = 46
341         WinAccountSchemaAdminsSid                     = 47
342         WinAccountEnterpriseAdminsSid                 = 48
343         WinAccountPolicyAdminsSid                     = 49
344         WinAccountRasAndIasServersSid                 = 50
345         WinNTLMAuthenticationSid                      = 51
346         WinDigestAuthenticationSid                    = 52
347         WinSChannelAuthenticationSid                  = 53
348         WinThisOrganizationSid                        = 54
349         WinOtherOrganizationSid                       = 55
350         WinBuiltinIncomingForestTrustBuildersSid      = 56
351         WinBuiltinPerfMonitoringUsersSid              = 57
352         WinBuiltinPerfLoggingUsersSid                 = 58
353         WinBuiltinAuthorizationAccessSid              = 59
354         WinBuiltinTerminalServerLicenseServersSid     = 60
355         WinBuiltinDCOMUsersSid                        = 61
356         WinBuiltinIUsersSid                           = 62
357         WinIUserSid                                   = 63
358         WinBuiltinCryptoOperatorsSid                  = 64
359         WinUntrustedLabelSid                          = 65
360         WinLowLabelSid                                = 66
361         WinMediumLabelSid                             = 67
362         WinHighLabelSid                               = 68
363         WinSystemLabelSid                             = 69
364         WinWriteRestrictedCodeSid                     = 70
365         WinCreatorOwnerRightsSid                      = 71
366         WinCacheablePrincipalsGroupSid                = 72
367         WinNonCacheablePrincipalsGroupSid             = 73
368         WinEnterpriseReadonlyControllersSid           = 74
369         WinAccountReadonlyControllersSid              = 75
370         WinBuiltinEventLogReadersGroup                = 76
371         WinNewEnterpriseReadonlyControllersSid        = 77
372         WinBuiltinCertSvcDComAccessGroup              = 78
373         WinMediumPlusLabelSid                         = 79
374         WinLocalLogonSid                              = 80
375         WinConsoleLogonSid                            = 81
376         WinThisOrganizationCertificateSid             = 82
377         WinApplicationPackageAuthoritySid             = 83
378         WinBuiltinAnyPackageSid                       = 84
379         WinCapabilityInternetClientSid                = 85
380         WinCapabilityInternetClientServerSid          = 86
381         WinCapabilityPrivateNetworkClientServerSid    = 87
382         WinCapabilityPicturesLibrarySid               = 88
383         WinCapabilityVideosLibrarySid                 = 89
384         WinCapabilityMusicLibrarySid                  = 90
385         WinCapabilityDocumentsLibrarySid              = 91
386         WinCapabilitySharedUserCertificatesSid        = 92
387         WinCapabilityEnterpriseAuthenticationSid      = 93
388         WinCapabilityRemovableStorageSid              = 94
389         WinBuiltinRDSRemoteAccessServersSid           = 95
390         WinBuiltinRDSEndpointServersSid               = 96
391         WinBuiltinRDSManagementServersSid             = 97
392         WinUserModeDriversSid                         = 98
393         WinBuiltinHyperVAdminsSid                     = 99
394         WinAccountCloneableControllersSid             = 100
395         WinBuiltinAccessControlAssistanceOperatorsSid = 101
396         WinBuiltinRemoteManagementUsersSid            = 102
397         WinAuthenticationAuthorityAssertedSid         = 103
398         WinAuthenticationServiceAssertedSid           = 104
399         WinLocalAccountSid                            = 105
400         WinLocalAccountAndAdministratorSid            = 106
401         WinAccountProtectedUsersSid                   = 107
402         WinCapabilityAppointmentsSid                  = 108
403         WinCapabilityContactsSid                      = 109
404         WinAccountDefaultSystemManagedSid             = 110
405         WinBuiltinDefaultSystemManagedGroupSid        = 111
406         WinBuiltinStorageReplicaAdminsSid             = 112
407         WinAccountKeyAdminsSid                        = 113
408         WinAccountEnterpriseKeyAdminsSid              = 114
409         WinAuthenticationKeyTrustSid                  = 115
410         WinAuthenticationKeyPropertyMFASid            = 116
411         WinAuthenticationKeyPropertyAttestationSid    = 117
412         WinAuthenticationFreshKeyAuthSid              = 118
413         WinBuiltinDeviceOwnersSid                     = 119
414 )
415
416 // Creates a sid for a well-known predefined alias, generally using the constants of the form
417 // Win*Sid, for the local machine.
418 func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
419         return CreateWellKnownDomainSid(sidType, nil)
420 }
421
422 // Creates a sid for a well-known predefined alias, generally using the constants of the form
423 // Win*Sid, for the domain specified by the domainSid parameter.
424 func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
425         n := uint32(50)
426         for {
427                 b := make([]byte, n)
428                 sid := (*SID)(unsafe.Pointer(&b[0]))
429                 err := createWellKnownSid(sidType, domainSid, sid, &n)
430                 if err == nil {
431                         return sid, nil
432                 }
433                 if err != ERROR_INSUFFICIENT_BUFFER {
434                         return nil, err
435                 }
436                 if n <= uint32(len(b)) {
437                         return nil, err
438                 }
439         }
440 }
441
442 const (
443         // do not reorder
444         TOKEN_ASSIGN_PRIMARY = 1 << iota
445         TOKEN_DUPLICATE
446         TOKEN_IMPERSONATE
447         TOKEN_QUERY
448         TOKEN_QUERY_SOURCE
449         TOKEN_ADJUST_PRIVILEGES
450         TOKEN_ADJUST_GROUPS
451         TOKEN_ADJUST_DEFAULT
452         TOKEN_ADJUST_SESSIONID
453
454         TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
455                 TOKEN_ASSIGN_PRIMARY |
456                 TOKEN_DUPLICATE |
457                 TOKEN_IMPERSONATE |
458                 TOKEN_QUERY |
459                 TOKEN_QUERY_SOURCE |
460                 TOKEN_ADJUST_PRIVILEGES |
461                 TOKEN_ADJUST_GROUPS |
462                 TOKEN_ADJUST_DEFAULT |
463                 TOKEN_ADJUST_SESSIONID
464         TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
465         TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
466                 TOKEN_ADJUST_PRIVILEGES |
467                 TOKEN_ADJUST_GROUPS |
468                 TOKEN_ADJUST_DEFAULT
469         TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
470 )
471
472 const (
473         // do not reorder
474         TokenUser = 1 + iota
475         TokenGroups
476         TokenPrivileges
477         TokenOwner
478         TokenPrimaryGroup
479         TokenDefaultDacl
480         TokenSource
481         TokenType
482         TokenImpersonationLevel
483         TokenStatistics
484         TokenRestrictedSids
485         TokenSessionId
486         TokenGroupsAndPrivileges
487         TokenSessionReference
488         TokenSandBoxInert
489         TokenAuditPolicy
490         TokenOrigin
491         TokenElevationType
492         TokenLinkedToken
493         TokenElevation
494         TokenHasRestrictions
495         TokenAccessInformation
496         TokenVirtualizationAllowed
497         TokenVirtualizationEnabled
498         TokenIntegrityLevel
499         TokenUIAccess
500         TokenMandatoryPolicy
501         TokenLogonSid
502         MaxTokenInfoClass
503 )
504
505 type SIDAndAttributes struct {
506         Sid        *SID
507         Attributes uint32
508 }
509
510 type Tokenuser struct {
511         User SIDAndAttributes
512 }
513
514 type Tokenprimarygroup struct {
515         PrimaryGroup *SID
516 }
517
518 type Tokengroups struct {
519         GroupCount uint32
520         Groups     [1]SIDAndAttributes
521 }
522
523 // Authorization Functions
524 //sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
525 //sys   OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
526 //sys   GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
527 //sys   GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
528 //sys   getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
529
530 // An access token contains the security information for a logon session.
531 // The system creates an access token when a user logs on, and every
532 // process executed on behalf of the user has a copy of the token.
533 // The token identifies the user, the user's groups, and the user's
534 // privileges. The system uses the token to control access to securable
535 // objects and to control the ability of the user to perform various
536 // system-related operations on the local computer.
537 type Token Handle
538
539 // OpenCurrentProcessToken opens the access token
540 // associated with current process.
541 func OpenCurrentProcessToken() (Token, error) {
542         p, e := GetCurrentProcess()
543         if e != nil {
544                 return 0, e
545         }
546         var t Token
547         e = OpenProcessToken(p, TOKEN_QUERY, &t)
548         if e != nil {
549                 return 0, e
550         }
551         return t, nil
552 }
553
554 // Close releases access to access token.
555 func (t Token) Close() error {
556         return CloseHandle(Handle(t))
557 }
558
559 // getInfo retrieves a specified type of information about an access token.
560 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
561         n := uint32(initSize)
562         for {
563                 b := make([]byte, n)
564                 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
565                 if e == nil {
566                         return unsafe.Pointer(&b[0]), nil
567                 }
568                 if e != ERROR_INSUFFICIENT_BUFFER {
569                         return nil, e
570                 }
571                 if n <= uint32(len(b)) {
572                         return nil, e
573                 }
574         }
575 }
576
577 // GetTokenUser retrieves access token t user account information.
578 func (t Token) GetTokenUser() (*Tokenuser, error) {
579         i, e := t.getInfo(TokenUser, 50)
580         if e != nil {
581                 return nil, e
582         }
583         return (*Tokenuser)(i), nil
584 }
585
586 // GetTokenGroups retrieves group accounts associated with access token t.
587 func (t Token) GetTokenGroups() (*Tokengroups, error) {
588         i, e := t.getInfo(TokenGroups, 50)
589         if e != nil {
590                 return nil, e
591         }
592         return (*Tokengroups)(i), nil
593 }
594
595 // GetTokenPrimaryGroup retrieves access token t primary group information.
596 // A pointer to a SID structure representing a group that will become
597 // the primary group of any objects created by a process using this access token.
598 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
599         i, e := t.getInfo(TokenPrimaryGroup, 50)
600         if e != nil {
601                 return nil, e
602         }
603         return (*Tokenprimarygroup)(i), nil
604 }
605
606 // GetUserProfileDirectory retrieves path to the
607 // root directory of the access token t user's profile.
608 func (t Token) GetUserProfileDirectory() (string, error) {
609         n := uint32(100)
610         for {
611                 b := make([]uint16, n)
612                 e := GetUserProfileDirectory(t, &b[0], &n)
613                 if e == nil {
614                         return UTF16ToString(b), nil
615                 }
616                 if e != ERROR_INSUFFICIENT_BUFFER {
617                         return "", e
618                 }
619                 if n <= uint32(len(b)) {
620                         return "", e
621                 }
622         }
623 }
624
625 // GetSystemDirectory retrieves path to current location of the system
626 // directory, which is typically, though not always, C:\Windows\System32.
627 func GetSystemDirectory() (string, error) {
628         n := uint32(MAX_PATH)
629         for {
630                 b := make([]uint16, n)
631                 l, e := getSystemDirectory(&b[0], n)
632                 if e != nil {
633                         return "", e
634                 }
635                 if l <= n {
636                         return UTF16ToString(b[:l]), nil
637                 }
638                 n = l
639         }
640 }
641
642 // IsMember reports whether the access token t is a member of the provided SID.
643 func (t Token) IsMember(sid *SID) (bool, error) {
644         var b int32
645         if e := checkTokenMembership(t, sid, &b); e != nil {
646                 return false, e
647         }
648         return b != 0, nil
649 }