github.com/Andyfoo/golang/x/sys@v0.0.0-20190901054642-57c1bf301704/windows/security_windows.go (about)

     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	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
   174  //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
   175  //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
   176  //sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
   177  //sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
   178  //sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
   179  //sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
   180  
   181  // The security identifier (SID) structure is a variable-length
   182  // structure used to uniquely identify users or groups.
   183  type SID struct{}
   184  
   185  // StringToSid converts a string-format security identifier
   186  // SID into a valid, functional SID.
   187  func StringToSid(s string) (*SID, error) {
   188  	var sid *SID
   189  	p, e := UTF16PtrFromString(s)
   190  	if e != nil {
   191  		return nil, e
   192  	}
   193  	e = ConvertStringSidToSid(p, &sid)
   194  	if e != nil {
   195  		return nil, e
   196  	}
   197  	defer LocalFree((Handle)(unsafe.Pointer(sid)))
   198  	return sid.Copy()
   199  }
   200  
   201  // LookupSID retrieves a security identifier SID for the account
   202  // and the name of the domain on which the account was found.
   203  // System specify target computer to search.
   204  func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
   205  	if len(account) == 0 {
   206  		return nil, "", 0, syscall.EINVAL
   207  	}
   208  	acc, e := UTF16PtrFromString(account)
   209  	if e != nil {
   210  		return nil, "", 0, e
   211  	}
   212  	var sys *uint16
   213  	if len(system) > 0 {
   214  		sys, e = UTF16PtrFromString(system)
   215  		if e != nil {
   216  			return nil, "", 0, e
   217  		}
   218  	}
   219  	n := uint32(50)
   220  	dn := uint32(50)
   221  	for {
   222  		b := make([]byte, n)
   223  		db := make([]uint16, dn)
   224  		sid = (*SID)(unsafe.Pointer(&b[0]))
   225  		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
   226  		if e == nil {
   227  			return sid, UTF16ToString(db), accType, nil
   228  		}
   229  		if e != ERROR_INSUFFICIENT_BUFFER {
   230  			return nil, "", 0, e
   231  		}
   232  		if n <= uint32(len(b)) {
   233  			return nil, "", 0, e
   234  		}
   235  	}
   236  }
   237  
   238  // String converts SID to a string format
   239  // suitable for display, storage, or transmission.
   240  func (sid *SID) String() (string, error) {
   241  	var s *uint16
   242  	e := ConvertSidToStringSid(sid, &s)
   243  	if e != nil {
   244  		return "", e
   245  	}
   246  	defer LocalFree((Handle)(unsafe.Pointer(s)))
   247  	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
   248  }
   249  
   250  // Len returns the length, in bytes, of a valid security identifier SID.
   251  func (sid *SID) Len() int {
   252  	return int(GetLengthSid(sid))
   253  }
   254  
   255  // Copy creates a duplicate of security identifier SID.
   256  func (sid *SID) Copy() (*SID, error) {
   257  	b := make([]byte, sid.Len())
   258  	sid2 := (*SID)(unsafe.Pointer(&b[0]))
   259  	e := CopySid(uint32(len(b)), sid2, sid)
   260  	if e != nil {
   261  		return nil, e
   262  	}
   263  	return sid2, nil
   264  }
   265  
   266  // IdentifierAuthority returns the identifier authority of the SID.
   267  func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
   268  	return *getSidIdentifierAuthority(sid)
   269  }
   270  
   271  // SubAuthorityCount returns the number of sub-authorities in the SID.
   272  func (sid *SID) SubAuthorityCount() uint8 {
   273  	return *getSidSubAuthorityCount(sid)
   274  }
   275  
   276  // SubAuthority returns the sub-authority of the SID as specified by
   277  // the index, which must be less than sid.SubAuthorityCount().
   278  func (sid *SID) SubAuthority(idx uint32) uint32 {
   279  	if idx >= uint32(sid.SubAuthorityCount()) {
   280  		panic("sub-authority index out of range")
   281  	}
   282  	return *getSidSubAuthority(sid, idx)
   283  }
   284  
   285  // IsValid returns whether the SID has a valid revision and length.
   286  func (sid *SID) IsValid() bool {
   287  	return isValidSid(sid)
   288  }
   289  
   290  // Equals compares two SIDs for equality.
   291  func (sid *SID) Equals(sid2 *SID) bool {
   292  	return EqualSid(sid, sid2)
   293  }
   294  
   295  // IsWellKnown determines whether the SID matches the well-known sidType.
   296  func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
   297  	return isWellKnownSid(sid, sidType)
   298  }
   299  
   300  // LookupAccount retrieves the name of the account for this SID
   301  // and the name of the first domain on which this SID is found.
   302  // System specify target computer to search for.
   303  func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
   304  	var sys *uint16
   305  	if len(system) > 0 {
   306  		sys, err = UTF16PtrFromString(system)
   307  		if err != nil {
   308  			return "", "", 0, err
   309  		}
   310  	}
   311  	n := uint32(50)
   312  	dn := uint32(50)
   313  	for {
   314  		b := make([]uint16, n)
   315  		db := make([]uint16, dn)
   316  		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
   317  		if e == nil {
   318  			return UTF16ToString(b), UTF16ToString(db), accType, nil
   319  		}
   320  		if e != ERROR_INSUFFICIENT_BUFFER {
   321  			return "", "", 0, e
   322  		}
   323  		if n <= uint32(len(b)) {
   324  			return "", "", 0, e
   325  		}
   326  	}
   327  }
   328  
   329  // Various types of pre-specified SIDs that can be synthesized and compared at runtime.
   330  type WELL_KNOWN_SID_TYPE uint32
   331  
   332  const (
   333  	WinNullSid                                    = 0
   334  	WinWorldSid                                   = 1
   335  	WinLocalSid                                   = 2
   336  	WinCreatorOwnerSid                            = 3
   337  	WinCreatorGroupSid                            = 4
   338  	WinCreatorOwnerServerSid                      = 5
   339  	WinCreatorGroupServerSid                      = 6
   340  	WinNtAuthoritySid                             = 7
   341  	WinDialupSid                                  = 8
   342  	WinNetworkSid                                 = 9
   343  	WinBatchSid                                   = 10
   344  	WinInteractiveSid                             = 11
   345  	WinServiceSid                                 = 12
   346  	WinAnonymousSid                               = 13
   347  	WinProxySid                                   = 14
   348  	WinEnterpriseControllersSid                   = 15
   349  	WinSelfSid                                    = 16
   350  	WinAuthenticatedUserSid                       = 17
   351  	WinRestrictedCodeSid                          = 18
   352  	WinTerminalServerSid                          = 19
   353  	WinRemoteLogonIdSid                           = 20
   354  	WinLogonIdsSid                                = 21
   355  	WinLocalSystemSid                             = 22
   356  	WinLocalServiceSid                            = 23
   357  	WinNetworkServiceSid                          = 24
   358  	WinBuiltinDomainSid                           = 25
   359  	WinBuiltinAdministratorsSid                   = 26
   360  	WinBuiltinUsersSid                            = 27
   361  	WinBuiltinGuestsSid                           = 28
   362  	WinBuiltinPowerUsersSid                       = 29
   363  	WinBuiltinAccountOperatorsSid                 = 30
   364  	WinBuiltinSystemOperatorsSid                  = 31
   365  	WinBuiltinPrintOperatorsSid                   = 32
   366  	WinBuiltinBackupOperatorsSid                  = 33
   367  	WinBuiltinReplicatorSid                       = 34
   368  	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
   369  	WinBuiltinRemoteDesktopUsersSid               = 36
   370  	WinBuiltinNetworkConfigurationOperatorsSid    = 37
   371  	WinAccountAdministratorSid                    = 38
   372  	WinAccountGuestSid                            = 39
   373  	WinAccountKrbtgtSid                           = 40
   374  	WinAccountDomainAdminsSid                     = 41
   375  	WinAccountDomainUsersSid                      = 42
   376  	WinAccountDomainGuestsSid                     = 43
   377  	WinAccountComputersSid                        = 44
   378  	WinAccountControllersSid                      = 45
   379  	WinAccountCertAdminsSid                       = 46
   380  	WinAccountSchemaAdminsSid                     = 47
   381  	WinAccountEnterpriseAdminsSid                 = 48
   382  	WinAccountPolicyAdminsSid                     = 49
   383  	WinAccountRasAndIasServersSid                 = 50
   384  	WinNTLMAuthenticationSid                      = 51
   385  	WinDigestAuthenticationSid                    = 52
   386  	WinSChannelAuthenticationSid                  = 53
   387  	WinThisOrganizationSid                        = 54
   388  	WinOtherOrganizationSid                       = 55
   389  	WinBuiltinIncomingForestTrustBuildersSid      = 56
   390  	WinBuiltinPerfMonitoringUsersSid              = 57
   391  	WinBuiltinPerfLoggingUsersSid                 = 58
   392  	WinBuiltinAuthorizationAccessSid              = 59
   393  	WinBuiltinTerminalServerLicenseServersSid     = 60
   394  	WinBuiltinDCOMUsersSid                        = 61
   395  	WinBuiltinIUsersSid                           = 62
   396  	WinIUserSid                                   = 63
   397  	WinBuiltinCryptoOperatorsSid                  = 64
   398  	WinUntrustedLabelSid                          = 65
   399  	WinLowLabelSid                                = 66
   400  	WinMediumLabelSid                             = 67
   401  	WinHighLabelSid                               = 68
   402  	WinSystemLabelSid                             = 69
   403  	WinWriteRestrictedCodeSid                     = 70
   404  	WinCreatorOwnerRightsSid                      = 71
   405  	WinCacheablePrincipalsGroupSid                = 72
   406  	WinNonCacheablePrincipalsGroupSid             = 73
   407  	WinEnterpriseReadonlyControllersSid           = 74
   408  	WinAccountReadonlyControllersSid              = 75
   409  	WinBuiltinEventLogReadersGroup                = 76
   410  	WinNewEnterpriseReadonlyControllersSid        = 77
   411  	WinBuiltinCertSvcDComAccessGroup              = 78
   412  	WinMediumPlusLabelSid                         = 79
   413  	WinLocalLogonSid                              = 80
   414  	WinConsoleLogonSid                            = 81
   415  	WinThisOrganizationCertificateSid             = 82
   416  	WinApplicationPackageAuthoritySid             = 83
   417  	WinBuiltinAnyPackageSid                       = 84
   418  	WinCapabilityInternetClientSid                = 85
   419  	WinCapabilityInternetClientServerSid          = 86
   420  	WinCapabilityPrivateNetworkClientServerSid    = 87
   421  	WinCapabilityPicturesLibrarySid               = 88
   422  	WinCapabilityVideosLibrarySid                 = 89
   423  	WinCapabilityMusicLibrarySid                  = 90
   424  	WinCapabilityDocumentsLibrarySid              = 91
   425  	WinCapabilitySharedUserCertificatesSid        = 92
   426  	WinCapabilityEnterpriseAuthenticationSid      = 93
   427  	WinCapabilityRemovableStorageSid              = 94
   428  	WinBuiltinRDSRemoteAccessServersSid           = 95
   429  	WinBuiltinRDSEndpointServersSid               = 96
   430  	WinBuiltinRDSManagementServersSid             = 97
   431  	WinUserModeDriversSid                         = 98
   432  	WinBuiltinHyperVAdminsSid                     = 99
   433  	WinAccountCloneableControllersSid             = 100
   434  	WinBuiltinAccessControlAssistanceOperatorsSid = 101
   435  	WinBuiltinRemoteManagementUsersSid            = 102
   436  	WinAuthenticationAuthorityAssertedSid         = 103
   437  	WinAuthenticationServiceAssertedSid           = 104
   438  	WinLocalAccountSid                            = 105
   439  	WinLocalAccountAndAdministratorSid            = 106
   440  	WinAccountProtectedUsersSid                   = 107
   441  	WinCapabilityAppointmentsSid                  = 108
   442  	WinCapabilityContactsSid                      = 109
   443  	WinAccountDefaultSystemManagedSid             = 110
   444  	WinBuiltinDefaultSystemManagedGroupSid        = 111
   445  	WinBuiltinStorageReplicaAdminsSid             = 112
   446  	WinAccountKeyAdminsSid                        = 113
   447  	WinAccountEnterpriseKeyAdminsSid              = 114
   448  	WinAuthenticationKeyTrustSid                  = 115
   449  	WinAuthenticationKeyPropertyMFASid            = 116
   450  	WinAuthenticationKeyPropertyAttestationSid    = 117
   451  	WinAuthenticationFreshKeyAuthSid              = 118
   452  	WinBuiltinDeviceOwnersSid                     = 119
   453  )
   454  
   455  // Creates a SID for a well-known predefined alias, generally using the constants of the form
   456  // Win*Sid, for the local machine.
   457  func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
   458  	return CreateWellKnownDomainSid(sidType, nil)
   459  }
   460  
   461  // Creates a SID for a well-known predefined alias, generally using the constants of the form
   462  // Win*Sid, for the domain specified by the domainSid parameter.
   463  func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
   464  	n := uint32(50)
   465  	for {
   466  		b := make([]byte, n)
   467  		sid := (*SID)(unsafe.Pointer(&b[0]))
   468  		err := createWellKnownSid(sidType, domainSid, sid, &n)
   469  		if err == nil {
   470  			return sid, nil
   471  		}
   472  		if err != ERROR_INSUFFICIENT_BUFFER {
   473  			return nil, err
   474  		}
   475  		if n <= uint32(len(b)) {
   476  			return nil, err
   477  		}
   478  	}
   479  }
   480  
   481  const (
   482  	// do not reorder
   483  	TOKEN_ASSIGN_PRIMARY = 1 << iota
   484  	TOKEN_DUPLICATE
   485  	TOKEN_IMPERSONATE
   486  	TOKEN_QUERY
   487  	TOKEN_QUERY_SOURCE
   488  	TOKEN_ADJUST_PRIVILEGES
   489  	TOKEN_ADJUST_GROUPS
   490  	TOKEN_ADJUST_DEFAULT
   491  	TOKEN_ADJUST_SESSIONID
   492  
   493  	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
   494  		TOKEN_ASSIGN_PRIMARY |
   495  		TOKEN_DUPLICATE |
   496  		TOKEN_IMPERSONATE |
   497  		TOKEN_QUERY |
   498  		TOKEN_QUERY_SOURCE |
   499  		TOKEN_ADJUST_PRIVILEGES |
   500  		TOKEN_ADJUST_GROUPS |
   501  		TOKEN_ADJUST_DEFAULT |
   502  		TOKEN_ADJUST_SESSIONID
   503  	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
   504  	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
   505  		TOKEN_ADJUST_PRIVILEGES |
   506  		TOKEN_ADJUST_GROUPS |
   507  		TOKEN_ADJUST_DEFAULT
   508  	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
   509  )
   510  
   511  const (
   512  	// do not reorder
   513  	TokenUser = 1 + iota
   514  	TokenGroups
   515  	TokenPrivileges
   516  	TokenOwner
   517  	TokenPrimaryGroup
   518  	TokenDefaultDacl
   519  	TokenSource
   520  	TokenType
   521  	TokenImpersonationLevel
   522  	TokenStatistics
   523  	TokenRestrictedSids
   524  	TokenSessionId
   525  	TokenGroupsAndPrivileges
   526  	TokenSessionReference
   527  	TokenSandBoxInert
   528  	TokenAuditPolicy
   529  	TokenOrigin
   530  	TokenElevationType
   531  	TokenLinkedToken
   532  	TokenElevation
   533  	TokenHasRestrictions
   534  	TokenAccessInformation
   535  	TokenVirtualizationAllowed
   536  	TokenVirtualizationEnabled
   537  	TokenIntegrityLevel
   538  	TokenUIAccess
   539  	TokenMandatoryPolicy
   540  	TokenLogonSid
   541  	MaxTokenInfoClass
   542  )
   543  
   544  // Group attributes inside of Tokengroups.Groups[i].Attributes
   545  const (
   546  	SE_GROUP_MANDATORY          = 0x00000001
   547  	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
   548  	SE_GROUP_ENABLED            = 0x00000004
   549  	SE_GROUP_OWNER              = 0x00000008
   550  	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
   551  	SE_GROUP_INTEGRITY          = 0x00000020
   552  	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
   553  	SE_GROUP_LOGON_ID           = 0xC0000000
   554  	SE_GROUP_RESOURCE           = 0x20000000
   555  	SE_GROUP_VALID_ATTRIBUTES   = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_USE_FOR_DENY_ONLY | SE_GROUP_LOGON_ID | SE_GROUP_RESOURCE | SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED
   556  )
   557  
   558  // Privilege attributes
   559  const (
   560  	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
   561  	SE_PRIVILEGE_ENABLED            = 0x00000002
   562  	SE_PRIVILEGE_REMOVED            = 0x00000004
   563  	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
   564  	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
   565  )
   566  
   567  // Token types
   568  const (
   569  	TokenPrimary       = 1
   570  	TokenImpersonation = 2
   571  )
   572  
   573  // Impersonation levels
   574  const (
   575  	SecurityAnonymous      = 0
   576  	SecurityIdentification = 1
   577  	SecurityImpersonation  = 2
   578  	SecurityDelegation     = 3
   579  )
   580  
   581  type LUID struct {
   582  	LowPart  uint32
   583  	HighPart int32
   584  }
   585  
   586  type LUIDAndAttributes struct {
   587  	Luid       LUID
   588  	Attributes uint32
   589  }
   590  
   591  type SIDAndAttributes struct {
   592  	Sid        *SID
   593  	Attributes uint32
   594  }
   595  
   596  type Tokenuser struct {
   597  	User SIDAndAttributes
   598  }
   599  
   600  type Tokenprimarygroup struct {
   601  	PrimaryGroup *SID
   602  }
   603  
   604  type Tokengroups struct {
   605  	GroupCount uint32
   606  	Groups     [1]SIDAndAttributes // Use AllGroups() for iterating.
   607  }
   608  
   609  // AllGroups returns a slice that can be used to iterate over the groups in g.
   610  func (g *Tokengroups) AllGroups() []SIDAndAttributes {
   611  	return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]
   612  }
   613  
   614  type Tokenprivileges struct {
   615  	PrivilegeCount uint32
   616  	Privileges     [1]LUIDAndAttributes // Use AllPrivileges() for iterating.
   617  }
   618  
   619  // AllPrivileges returns a slice that can be used to iterate over the privileges in p.
   620  func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {
   621  	return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]
   622  }
   623  
   624  type Tokenmandatorylabel struct {
   625  	Label SIDAndAttributes
   626  }
   627  
   628  func (tml *Tokenmandatorylabel) Size() uint32 {
   629  	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
   630  }
   631  
   632  // Authorization Functions
   633  //sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
   634  //sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
   635  //sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
   636  //sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
   637  //sys	RevertToSelf() (err error) = advapi32.RevertToSelf
   638  //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
   639  //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
   640  //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
   641  //sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
   642  //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
   643  //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
   644  //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
   645  //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
   646  //sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
   647  //sys	getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW
   648  //sys	getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW
   649  
   650  // An access token contains the security information for a logon session.
   651  // The system creates an access token when a user logs on, and every
   652  // process executed on behalf of the user has a copy of the token.
   653  // The token identifies the user, the user's groups, and the user's
   654  // privileges. The system uses the token to control access to securable
   655  // objects and to control the ability of the user to perform various
   656  // system-related operations on the local computer.
   657  type Token Handle
   658  
   659  // OpenCurrentProcessToken opens the access token
   660  // associated with current process. It is a real
   661  // token that needs to be closed, unlike
   662  // GetCurrentProcessToken.
   663  func OpenCurrentProcessToken() (Token, error) {
   664  	p, e := GetCurrentProcess()
   665  	if e != nil {
   666  		return 0, e
   667  	}
   668  	var t Token
   669  	e = OpenProcessToken(p, TOKEN_QUERY, &t)
   670  	if e != nil {
   671  		return 0, e
   672  	}
   673  	return t, nil
   674  }
   675  
   676  // GetCurrentProcessToken returns the access token associated with
   677  // the current process. It is a pseudo token that does not need
   678  // to be closed.
   679  func GetCurrentProcessToken() Token {
   680  	return Token(^uintptr(4 - 1))
   681  }
   682  
   683  // GetCurrentThreadToken return the access token associated with
   684  // the current thread. It is a pseudo token that does not need
   685  // to be closed.
   686  func GetCurrentThreadToken() Token {
   687  	return Token(^uintptr(5 - 1))
   688  }
   689  
   690  // GetCurrentThreadEffectiveToken returns the effective access token
   691  // associated with the current thread. It is a pseudo token that does
   692  // not need to be closed.
   693  func GetCurrentThreadEffectiveToken() Token {
   694  	return Token(^uintptr(6 - 1))
   695  }
   696  
   697  // Close releases access to access token.
   698  func (t Token) Close() error {
   699  	return CloseHandle(Handle(t))
   700  }
   701  
   702  // getInfo retrieves a specified type of information about an access token.
   703  func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
   704  	n := uint32(initSize)
   705  	for {
   706  		b := make([]byte, n)
   707  		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
   708  		if e == nil {
   709  			return unsafe.Pointer(&b[0]), nil
   710  		}
   711  		if e != ERROR_INSUFFICIENT_BUFFER {
   712  			return nil, e
   713  		}
   714  		if n <= uint32(len(b)) {
   715  			return nil, e
   716  		}
   717  	}
   718  }
   719  
   720  // GetTokenUser retrieves access token t user account information.
   721  func (t Token) GetTokenUser() (*Tokenuser, error) {
   722  	i, e := t.getInfo(TokenUser, 50)
   723  	if e != nil {
   724  		return nil, e
   725  	}
   726  	return (*Tokenuser)(i), nil
   727  }
   728  
   729  // GetTokenGroups retrieves group accounts associated with access token t.
   730  func (t Token) GetTokenGroups() (*Tokengroups, error) {
   731  	i, e := t.getInfo(TokenGroups, 50)
   732  	if e != nil {
   733  		return nil, e
   734  	}
   735  	return (*Tokengroups)(i), nil
   736  }
   737  
   738  // GetTokenPrimaryGroup retrieves access token t primary group information.
   739  // A pointer to a SID structure representing a group that will become
   740  // the primary group of any objects created by a process using this access token.
   741  func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
   742  	i, e := t.getInfo(TokenPrimaryGroup, 50)
   743  	if e != nil {
   744  		return nil, e
   745  	}
   746  	return (*Tokenprimarygroup)(i), nil
   747  }
   748  
   749  // GetUserProfileDirectory retrieves path to the
   750  // root directory of the access token t user's profile.
   751  func (t Token) GetUserProfileDirectory() (string, error) {
   752  	n := uint32(100)
   753  	for {
   754  		b := make([]uint16, n)
   755  		e := GetUserProfileDirectory(t, &b[0], &n)
   756  		if e == nil {
   757  			return UTF16ToString(b), nil
   758  		}
   759  		if e != ERROR_INSUFFICIENT_BUFFER {
   760  			return "", e
   761  		}
   762  		if n <= uint32(len(b)) {
   763  			return "", e
   764  		}
   765  	}
   766  }
   767  
   768  // IsElevated returns whether the current token is elevated from a UAC perspective.
   769  func (token Token) IsElevated() bool {
   770  	var isElevated uint32
   771  	var outLen uint32
   772  	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
   773  	if err != nil {
   774  		return false
   775  	}
   776  	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
   777  }
   778  
   779  // GetLinkedToken returns the linked token, which may be an elevated UAC token.
   780  func (token Token) GetLinkedToken() (Token, error) {
   781  	var linkedToken Token
   782  	var outLen uint32
   783  	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
   784  	if err != nil {
   785  		return Token(0), err
   786  	}
   787  	return linkedToken, nil
   788  }
   789  
   790  // GetSystemDirectory retrieves the path to current location of the system
   791  // directory, which is typically, though not always, `C:\Windows\System32`.
   792  func GetSystemDirectory() (string, error) {
   793  	n := uint32(MAX_PATH)
   794  	for {
   795  		b := make([]uint16, n)
   796  		l, e := getSystemDirectory(&b[0], n)
   797  		if e != nil {
   798  			return "", e
   799  		}
   800  		if l <= n {
   801  			return UTF16ToString(b[:l]), nil
   802  		}
   803  		n = l
   804  	}
   805  }
   806  
   807  // GetWindowsDirectory retrieves the path to current location of the Windows
   808  // directory, which is typically, though not always, `C:\Windows`. This may
   809  // be a private user directory in the case that the application is running
   810  // under a terminal server.
   811  func GetWindowsDirectory() (string, error) {
   812  	n := uint32(MAX_PATH)
   813  	for {
   814  		b := make([]uint16, n)
   815  		l, e := getWindowsDirectory(&b[0], n)
   816  		if e != nil {
   817  			return "", e
   818  		}
   819  		if l <= n {
   820  			return UTF16ToString(b[:l]), nil
   821  		}
   822  		n = l
   823  	}
   824  }
   825  
   826  // GetSystemWindowsDirectory retrieves the path to current location of the
   827  // Windows directory, which is typically, though not always, `C:\Windows`.
   828  func GetSystemWindowsDirectory() (string, error) {
   829  	n := uint32(MAX_PATH)
   830  	for {
   831  		b := make([]uint16, n)
   832  		l, e := getSystemWindowsDirectory(&b[0], n)
   833  		if e != nil {
   834  			return "", e
   835  		}
   836  		if l <= n {
   837  			return UTF16ToString(b[:l]), nil
   838  		}
   839  		n = l
   840  	}
   841  }
   842  
   843  // IsMember reports whether the access token t is a member of the provided SID.
   844  func (t Token) IsMember(sid *SID) (bool, error) {
   845  	var b int32
   846  	if e := checkTokenMembership(t, sid, &b); e != nil {
   847  		return false, e
   848  	}
   849  	return b != 0, nil
   850  }
   851  
   852  const (
   853  	WTS_CONSOLE_CONNECT        = 0x1
   854  	WTS_CONSOLE_DISCONNECT     = 0x2
   855  	WTS_REMOTE_CONNECT         = 0x3
   856  	WTS_REMOTE_DISCONNECT      = 0x4
   857  	WTS_SESSION_LOGON          = 0x5
   858  	WTS_SESSION_LOGOFF         = 0x6
   859  	WTS_SESSION_LOCK           = 0x7
   860  	WTS_SESSION_UNLOCK         = 0x8
   861  	WTS_SESSION_REMOTE_CONTROL = 0x9
   862  	WTS_SESSION_CREATE         = 0xa
   863  	WTS_SESSION_TERMINATE      = 0xb
   864  )
   865  
   866  const (
   867  	WTSActive       = 0
   868  	WTSConnected    = 1
   869  	WTSConnectQuery = 2
   870  	WTSShadow       = 3
   871  	WTSDisconnected = 4
   872  	WTSIdle         = 5
   873  	WTSListen       = 6
   874  	WTSReset        = 7
   875  	WTSDown         = 8
   876  	WTSInit         = 9
   877  )
   878  
   879  type WTSSESSION_NOTIFICATION struct {
   880  	Size      uint32
   881  	SessionID uint32
   882  }
   883  
   884  type WTS_SESSION_INFO struct {
   885  	SessionID         uint32
   886  	WindowStationName *uint16
   887  	State             uint32
   888  }
   889  
   890  //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
   891  //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
   892  //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory