twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

security_windows.go (52188B)


      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 	"golang.org/x/sys/internal/unsafeheader"
     12 )
     13 
     14 const (
     15 	NameUnknown          = 0
     16 	NameFullyQualifiedDN = 1
     17 	NameSamCompatible    = 2
     18 	NameDisplay          = 3
     19 	NameUniqueId         = 6
     20 	NameCanonical        = 7
     21 	NameUserPrincipal    = 8
     22 	NameCanonicalEx      = 9
     23 	NameServicePrincipal = 10
     24 	NameDnsDomain        = 12
     25 )
     26 
     27 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
     28 // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
     29 //sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
     30 //sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
     31 
     32 // TranslateAccountName converts a directory service
     33 // object name from one format to another.
     34 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
     35 	u, e := UTF16PtrFromString(username)
     36 	if e != nil {
     37 		return "", e
     38 	}
     39 	n := uint32(50)
     40 	for {
     41 		b := make([]uint16, n)
     42 		e = TranslateName(u, from, to, &b[0], &n)
     43 		if e == nil {
     44 			return UTF16ToString(b[:n]), nil
     45 		}
     46 		if e != ERROR_INSUFFICIENT_BUFFER {
     47 			return "", e
     48 		}
     49 		if n <= uint32(len(b)) {
     50 			return "", e
     51 		}
     52 	}
     53 }
     54 
     55 const (
     56 	// do not reorder
     57 	NetSetupUnknownStatus = iota
     58 	NetSetupUnjoined
     59 	NetSetupWorkgroupName
     60 	NetSetupDomainName
     61 )
     62 
     63 type UserInfo10 struct {
     64 	Name       *uint16
     65 	Comment    *uint16
     66 	UsrComment *uint16
     67 	FullName   *uint16
     68 }
     69 
     70 //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
     71 //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
     72 //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
     73 
     74 const (
     75 	// do not reorder
     76 	SidTypeUser = 1 + iota
     77 	SidTypeGroup
     78 	SidTypeDomain
     79 	SidTypeAlias
     80 	SidTypeWellKnownGroup
     81 	SidTypeDeletedAccount
     82 	SidTypeInvalid
     83 	SidTypeUnknown
     84 	SidTypeComputer
     85 	SidTypeLabel
     86 )
     87 
     88 type SidIdentifierAuthority struct {
     89 	Value [6]byte
     90 }
     91 
     92 var (
     93 	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
     94 	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
     95 	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
     96 	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
     97 	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
     98 	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
     99 	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
    100 )
    101 
    102 const (
    103 	SECURITY_NULL_RID                   = 0
    104 	SECURITY_WORLD_RID                  = 0
    105 	SECURITY_LOCAL_RID                  = 0
    106 	SECURITY_CREATOR_OWNER_RID          = 0
    107 	SECURITY_CREATOR_GROUP_RID          = 1
    108 	SECURITY_DIALUP_RID                 = 1
    109 	SECURITY_NETWORK_RID                = 2
    110 	SECURITY_BATCH_RID                  = 3
    111 	SECURITY_INTERACTIVE_RID            = 4
    112 	SECURITY_LOGON_IDS_RID              = 5
    113 	SECURITY_SERVICE_RID                = 6
    114 	SECURITY_LOCAL_SYSTEM_RID           = 18
    115 	SECURITY_BUILTIN_DOMAIN_RID         = 32
    116 	SECURITY_PRINCIPAL_SELF_RID         = 10
    117 	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
    118 	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
    119 	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
    120 	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
    121 	SECURITY_PROXY_RID                  = 0x8
    122 	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
    123 	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
    124 	SECURITY_AUTHENTICATED_USER_RID     = 0xb
    125 	SECURITY_RESTRICTED_CODE_RID        = 0xc
    126 	SECURITY_NT_NON_UNIQUE_RID          = 0x15
    127 )
    128 
    129 // Predefined domain-relative RIDs for local groups.
    130 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
    131 const (
    132 	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
    133 	DOMAIN_ALIAS_RID_USERS                          = 0x221
    134 	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
    135 	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
    136 	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
    137 	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
    138 	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
    139 	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
    140 	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
    141 	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
    142 	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
    143 	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
    144 	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
    145 	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
    146 	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
    147 	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
    148 	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
    149 	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
    150 	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
    151 	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
    152 	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
    153 	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
    154 	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
    155 	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
    156 	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
    157 )
    158 
    159 //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
    160 //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
    161 //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
    162 //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
    163 //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
    164 //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
    165 //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
    166 //sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
    167 //sys	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
    168 //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
    169 //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
    170 //sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
    171 //sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
    172 //sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
    173 //sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
    174 
    175 // The security identifier (SID) structure is a variable-length
    176 // structure used to uniquely identify users or groups.
    177 type SID struct{}
    178 
    179 // StringToSid converts a string-format security identifier
    180 // SID into a valid, functional SID.
    181 func StringToSid(s string) (*SID, error) {
    182 	var sid *SID
    183 	p, e := UTF16PtrFromString(s)
    184 	if e != nil {
    185 		return nil, e
    186 	}
    187 	e = ConvertStringSidToSid(p, &sid)
    188 	if e != nil {
    189 		return nil, e
    190 	}
    191 	defer LocalFree((Handle)(unsafe.Pointer(sid)))
    192 	return sid.Copy()
    193 }
    194 
    195 // LookupSID retrieves a security identifier SID for the account
    196 // and the name of the domain on which the account was found.
    197 // System specify target computer to search.
    198 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
    199 	if len(account) == 0 {
    200 		return nil, "", 0, syscall.EINVAL
    201 	}
    202 	acc, e := UTF16PtrFromString(account)
    203 	if e != nil {
    204 		return nil, "", 0, e
    205 	}
    206 	var sys *uint16
    207 	if len(system) > 0 {
    208 		sys, e = UTF16PtrFromString(system)
    209 		if e != nil {
    210 			return nil, "", 0, e
    211 		}
    212 	}
    213 	n := uint32(50)
    214 	dn := uint32(50)
    215 	for {
    216 		b := make([]byte, n)
    217 		db := make([]uint16, dn)
    218 		sid = (*SID)(unsafe.Pointer(&b[0]))
    219 		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
    220 		if e == nil {
    221 			return sid, UTF16ToString(db), accType, nil
    222 		}
    223 		if e != ERROR_INSUFFICIENT_BUFFER {
    224 			return nil, "", 0, e
    225 		}
    226 		if n <= uint32(len(b)) {
    227 			return nil, "", 0, e
    228 		}
    229 	}
    230 }
    231 
    232 // String converts SID to a string format suitable for display, storage, or transmission.
    233 func (sid *SID) String() string {
    234 	var s *uint16
    235 	e := ConvertSidToStringSid(sid, &s)
    236 	if e != nil {
    237 		return ""
    238 	}
    239 	defer LocalFree((Handle)(unsafe.Pointer(s)))
    240 	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:])
    241 }
    242 
    243 // Len returns the length, in bytes, of a valid security identifier SID.
    244 func (sid *SID) Len() int {
    245 	return int(GetLengthSid(sid))
    246 }
    247 
    248 // Copy creates a duplicate of security identifier SID.
    249 func (sid *SID) Copy() (*SID, error) {
    250 	b := make([]byte, sid.Len())
    251 	sid2 := (*SID)(unsafe.Pointer(&b[0]))
    252 	e := CopySid(uint32(len(b)), sid2, sid)
    253 	if e != nil {
    254 		return nil, e
    255 	}
    256 	return sid2, nil
    257 }
    258 
    259 // IdentifierAuthority returns the identifier authority of the SID.
    260 func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
    261 	return *getSidIdentifierAuthority(sid)
    262 }
    263 
    264 // SubAuthorityCount returns the number of sub-authorities in the SID.
    265 func (sid *SID) SubAuthorityCount() uint8 {
    266 	return *getSidSubAuthorityCount(sid)
    267 }
    268 
    269 // SubAuthority returns the sub-authority of the SID as specified by
    270 // the index, which must be less than sid.SubAuthorityCount().
    271 func (sid *SID) SubAuthority(idx uint32) uint32 {
    272 	if idx >= uint32(sid.SubAuthorityCount()) {
    273 		panic("sub-authority index out of range")
    274 	}
    275 	return *getSidSubAuthority(sid, idx)
    276 }
    277 
    278 // IsValid returns whether the SID has a valid revision and length.
    279 func (sid *SID) IsValid() bool {
    280 	return isValidSid(sid)
    281 }
    282 
    283 // Equals compares two SIDs for equality.
    284 func (sid *SID) Equals(sid2 *SID) bool {
    285 	return EqualSid(sid, sid2)
    286 }
    287 
    288 // IsWellKnown determines whether the SID matches the well-known sidType.
    289 func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
    290 	return isWellKnownSid(sid, sidType)
    291 }
    292 
    293 // LookupAccount retrieves the name of the account for this SID
    294 // and the name of the first domain on which this SID is found.
    295 // System specify target computer to search for.
    296 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
    297 	var sys *uint16
    298 	if len(system) > 0 {
    299 		sys, err = UTF16PtrFromString(system)
    300 		if err != nil {
    301 			return "", "", 0, err
    302 		}
    303 	}
    304 	n := uint32(50)
    305 	dn := uint32(50)
    306 	for {
    307 		b := make([]uint16, n)
    308 		db := make([]uint16, dn)
    309 		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
    310 		if e == nil {
    311 			return UTF16ToString(b), UTF16ToString(db), accType, nil
    312 		}
    313 		if e != ERROR_INSUFFICIENT_BUFFER {
    314 			return "", "", 0, e
    315 		}
    316 		if n <= uint32(len(b)) {
    317 			return "", "", 0, e
    318 		}
    319 	}
    320 }
    321 
    322 // Various types of pre-specified SIDs that can be synthesized and compared at runtime.
    323 type WELL_KNOWN_SID_TYPE uint32
    324 
    325 const (
    326 	WinNullSid                                    = 0
    327 	WinWorldSid                                   = 1
    328 	WinLocalSid                                   = 2
    329 	WinCreatorOwnerSid                            = 3
    330 	WinCreatorGroupSid                            = 4
    331 	WinCreatorOwnerServerSid                      = 5
    332 	WinCreatorGroupServerSid                      = 6
    333 	WinNtAuthoritySid                             = 7
    334 	WinDialupSid                                  = 8
    335 	WinNetworkSid                                 = 9
    336 	WinBatchSid                                   = 10
    337 	WinInteractiveSid                             = 11
    338 	WinServiceSid                                 = 12
    339 	WinAnonymousSid                               = 13
    340 	WinProxySid                                   = 14
    341 	WinEnterpriseControllersSid                   = 15
    342 	WinSelfSid                                    = 16
    343 	WinAuthenticatedUserSid                       = 17
    344 	WinRestrictedCodeSid                          = 18
    345 	WinTerminalServerSid                          = 19
    346 	WinRemoteLogonIdSid                           = 20
    347 	WinLogonIdsSid                                = 21
    348 	WinLocalSystemSid                             = 22
    349 	WinLocalServiceSid                            = 23
    350 	WinNetworkServiceSid                          = 24
    351 	WinBuiltinDomainSid                           = 25
    352 	WinBuiltinAdministratorsSid                   = 26
    353 	WinBuiltinUsersSid                            = 27
    354 	WinBuiltinGuestsSid                           = 28
    355 	WinBuiltinPowerUsersSid                       = 29
    356 	WinBuiltinAccountOperatorsSid                 = 30
    357 	WinBuiltinSystemOperatorsSid                  = 31
    358 	WinBuiltinPrintOperatorsSid                   = 32
    359 	WinBuiltinBackupOperatorsSid                  = 33
    360 	WinBuiltinReplicatorSid                       = 34
    361 	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
    362 	WinBuiltinRemoteDesktopUsersSid               = 36
    363 	WinBuiltinNetworkConfigurationOperatorsSid    = 37
    364 	WinAccountAdministratorSid                    = 38
    365 	WinAccountGuestSid                            = 39
    366 	WinAccountKrbtgtSid                           = 40
    367 	WinAccountDomainAdminsSid                     = 41
    368 	WinAccountDomainUsersSid                      = 42
    369 	WinAccountDomainGuestsSid                     = 43
    370 	WinAccountComputersSid                        = 44
    371 	WinAccountControllersSid                      = 45
    372 	WinAccountCertAdminsSid                       = 46
    373 	WinAccountSchemaAdminsSid                     = 47
    374 	WinAccountEnterpriseAdminsSid                 = 48
    375 	WinAccountPolicyAdminsSid                     = 49
    376 	WinAccountRasAndIasServersSid                 = 50
    377 	WinNTLMAuthenticationSid                      = 51
    378 	WinDigestAuthenticationSid                    = 52
    379 	WinSChannelAuthenticationSid                  = 53
    380 	WinThisOrganizationSid                        = 54
    381 	WinOtherOrganizationSid                       = 55
    382 	WinBuiltinIncomingForestTrustBuildersSid      = 56
    383 	WinBuiltinPerfMonitoringUsersSid              = 57
    384 	WinBuiltinPerfLoggingUsersSid                 = 58
    385 	WinBuiltinAuthorizationAccessSid              = 59
    386 	WinBuiltinTerminalServerLicenseServersSid     = 60
    387 	WinBuiltinDCOMUsersSid                        = 61
    388 	WinBuiltinIUsersSid                           = 62
    389 	WinIUserSid                                   = 63
    390 	WinBuiltinCryptoOperatorsSid                  = 64
    391 	WinUntrustedLabelSid                          = 65
    392 	WinLowLabelSid                                = 66
    393 	WinMediumLabelSid                             = 67
    394 	WinHighLabelSid                               = 68
    395 	WinSystemLabelSid                             = 69
    396 	WinWriteRestrictedCodeSid                     = 70
    397 	WinCreatorOwnerRightsSid                      = 71
    398 	WinCacheablePrincipalsGroupSid                = 72
    399 	WinNonCacheablePrincipalsGroupSid             = 73
    400 	WinEnterpriseReadonlyControllersSid           = 74
    401 	WinAccountReadonlyControllersSid              = 75
    402 	WinBuiltinEventLogReadersGroup                = 76
    403 	WinNewEnterpriseReadonlyControllersSid        = 77
    404 	WinBuiltinCertSvcDComAccessGroup              = 78
    405 	WinMediumPlusLabelSid                         = 79
    406 	WinLocalLogonSid                              = 80
    407 	WinConsoleLogonSid                            = 81
    408 	WinThisOrganizationCertificateSid             = 82
    409 	WinApplicationPackageAuthoritySid             = 83
    410 	WinBuiltinAnyPackageSid                       = 84
    411 	WinCapabilityInternetClientSid                = 85
    412 	WinCapabilityInternetClientServerSid          = 86
    413 	WinCapabilityPrivateNetworkClientServerSid    = 87
    414 	WinCapabilityPicturesLibrarySid               = 88
    415 	WinCapabilityVideosLibrarySid                 = 89
    416 	WinCapabilityMusicLibrarySid                  = 90
    417 	WinCapabilityDocumentsLibrarySid              = 91
    418 	WinCapabilitySharedUserCertificatesSid        = 92
    419 	WinCapabilityEnterpriseAuthenticationSid      = 93
    420 	WinCapabilityRemovableStorageSid              = 94
    421 	WinBuiltinRDSRemoteAccessServersSid           = 95
    422 	WinBuiltinRDSEndpointServersSid               = 96
    423 	WinBuiltinRDSManagementServersSid             = 97
    424 	WinUserModeDriversSid                         = 98
    425 	WinBuiltinHyperVAdminsSid                     = 99
    426 	WinAccountCloneableControllersSid             = 100
    427 	WinBuiltinAccessControlAssistanceOperatorsSid = 101
    428 	WinBuiltinRemoteManagementUsersSid            = 102
    429 	WinAuthenticationAuthorityAssertedSid         = 103
    430 	WinAuthenticationServiceAssertedSid           = 104
    431 	WinLocalAccountSid                            = 105
    432 	WinLocalAccountAndAdministratorSid            = 106
    433 	WinAccountProtectedUsersSid                   = 107
    434 	WinCapabilityAppointmentsSid                  = 108
    435 	WinCapabilityContactsSid                      = 109
    436 	WinAccountDefaultSystemManagedSid             = 110
    437 	WinBuiltinDefaultSystemManagedGroupSid        = 111
    438 	WinBuiltinStorageReplicaAdminsSid             = 112
    439 	WinAccountKeyAdminsSid                        = 113
    440 	WinAccountEnterpriseKeyAdminsSid              = 114
    441 	WinAuthenticationKeyTrustSid                  = 115
    442 	WinAuthenticationKeyPropertyMFASid            = 116
    443 	WinAuthenticationKeyPropertyAttestationSid    = 117
    444 	WinAuthenticationFreshKeyAuthSid              = 118
    445 	WinBuiltinDeviceOwnersSid                     = 119
    446 )
    447 
    448 // Creates a SID for a well-known predefined alias, generally using the constants of the form
    449 // Win*Sid, for the local machine.
    450 func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
    451 	return CreateWellKnownDomainSid(sidType, nil)
    452 }
    453 
    454 // Creates a SID for a well-known predefined alias, generally using the constants of the form
    455 // Win*Sid, for the domain specified by the domainSid parameter.
    456 func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
    457 	n := uint32(50)
    458 	for {
    459 		b := make([]byte, n)
    460 		sid := (*SID)(unsafe.Pointer(&b[0]))
    461 		err := createWellKnownSid(sidType, domainSid, sid, &n)
    462 		if err == nil {
    463 			return sid, nil
    464 		}
    465 		if err != ERROR_INSUFFICIENT_BUFFER {
    466 			return nil, err
    467 		}
    468 		if n <= uint32(len(b)) {
    469 			return nil, err
    470 		}
    471 	}
    472 }
    473 
    474 const (
    475 	// do not reorder
    476 	TOKEN_ASSIGN_PRIMARY = 1 << iota
    477 	TOKEN_DUPLICATE
    478 	TOKEN_IMPERSONATE
    479 	TOKEN_QUERY
    480 	TOKEN_QUERY_SOURCE
    481 	TOKEN_ADJUST_PRIVILEGES
    482 	TOKEN_ADJUST_GROUPS
    483 	TOKEN_ADJUST_DEFAULT
    484 	TOKEN_ADJUST_SESSIONID
    485 
    486 	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
    487 		TOKEN_ASSIGN_PRIMARY |
    488 		TOKEN_DUPLICATE |
    489 		TOKEN_IMPERSONATE |
    490 		TOKEN_QUERY |
    491 		TOKEN_QUERY_SOURCE |
    492 		TOKEN_ADJUST_PRIVILEGES |
    493 		TOKEN_ADJUST_GROUPS |
    494 		TOKEN_ADJUST_DEFAULT |
    495 		TOKEN_ADJUST_SESSIONID
    496 	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
    497 	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
    498 		TOKEN_ADJUST_PRIVILEGES |
    499 		TOKEN_ADJUST_GROUPS |
    500 		TOKEN_ADJUST_DEFAULT
    501 	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
    502 )
    503 
    504 const (
    505 	// do not reorder
    506 	TokenUser = 1 + iota
    507 	TokenGroups
    508 	TokenPrivileges
    509 	TokenOwner
    510 	TokenPrimaryGroup
    511 	TokenDefaultDacl
    512 	TokenSource
    513 	TokenType
    514 	TokenImpersonationLevel
    515 	TokenStatistics
    516 	TokenRestrictedSids
    517 	TokenSessionId
    518 	TokenGroupsAndPrivileges
    519 	TokenSessionReference
    520 	TokenSandBoxInert
    521 	TokenAuditPolicy
    522 	TokenOrigin
    523 	TokenElevationType
    524 	TokenLinkedToken
    525 	TokenElevation
    526 	TokenHasRestrictions
    527 	TokenAccessInformation
    528 	TokenVirtualizationAllowed
    529 	TokenVirtualizationEnabled
    530 	TokenIntegrityLevel
    531 	TokenUIAccess
    532 	TokenMandatoryPolicy
    533 	TokenLogonSid
    534 	MaxTokenInfoClass
    535 )
    536 
    537 // Group attributes inside of Tokengroups.Groups[i].Attributes
    538 const (
    539 	SE_GROUP_MANDATORY          = 0x00000001
    540 	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
    541 	SE_GROUP_ENABLED            = 0x00000004
    542 	SE_GROUP_OWNER              = 0x00000008
    543 	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
    544 	SE_GROUP_INTEGRITY          = 0x00000020
    545 	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
    546 	SE_GROUP_LOGON_ID           = 0xC0000000
    547 	SE_GROUP_RESOURCE           = 0x20000000
    548 	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
    549 )
    550 
    551 // Privilege attributes
    552 const (
    553 	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
    554 	SE_PRIVILEGE_ENABLED            = 0x00000002
    555 	SE_PRIVILEGE_REMOVED            = 0x00000004
    556 	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
    557 	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
    558 )
    559 
    560 // Token types
    561 const (
    562 	TokenPrimary       = 1
    563 	TokenImpersonation = 2
    564 )
    565 
    566 // Impersonation levels
    567 const (
    568 	SecurityAnonymous      = 0
    569 	SecurityIdentification = 1
    570 	SecurityImpersonation  = 2
    571 	SecurityDelegation     = 3
    572 )
    573 
    574 type LUID struct {
    575 	LowPart  uint32
    576 	HighPart int32
    577 }
    578 
    579 type LUIDAndAttributes struct {
    580 	Luid       LUID
    581 	Attributes uint32
    582 }
    583 
    584 type SIDAndAttributes struct {
    585 	Sid        *SID
    586 	Attributes uint32
    587 }
    588 
    589 type Tokenuser struct {
    590 	User SIDAndAttributes
    591 }
    592 
    593 type Tokenprimarygroup struct {
    594 	PrimaryGroup *SID
    595 }
    596 
    597 type Tokengroups struct {
    598 	GroupCount uint32
    599 	Groups     [1]SIDAndAttributes // Use AllGroups() for iterating.
    600 }
    601 
    602 // AllGroups returns a slice that can be used to iterate over the groups in g.
    603 func (g *Tokengroups) AllGroups() []SIDAndAttributes {
    604 	return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]
    605 }
    606 
    607 type Tokenprivileges struct {
    608 	PrivilegeCount uint32
    609 	Privileges     [1]LUIDAndAttributes // Use AllPrivileges() for iterating.
    610 }
    611 
    612 // AllPrivileges returns a slice that can be used to iterate over the privileges in p.
    613 func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {
    614 	return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]
    615 }
    616 
    617 type Tokenmandatorylabel struct {
    618 	Label SIDAndAttributes
    619 }
    620 
    621 func (tml *Tokenmandatorylabel) Size() uint32 {
    622 	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
    623 }
    624 
    625 // Authorization Functions
    626 //sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
    627 //sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
    628 //sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
    629 //sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
    630 //sys	RevertToSelf() (err error) = advapi32.RevertToSelf
    631 //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
    632 //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
    633 //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
    634 //sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
    635 //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
    636 //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
    637 //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
    638 //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
    639 //sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
    640 //sys	getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW
    641 //sys	getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW
    642 
    643 // An access token contains the security information for a logon session.
    644 // The system creates an access token when a user logs on, and every
    645 // process executed on behalf of the user has a copy of the token.
    646 // The token identifies the user, the user's groups, and the user's
    647 // privileges. The system uses the token to control access to securable
    648 // objects and to control the ability of the user to perform various
    649 // system-related operations on the local computer.
    650 type Token Handle
    651 
    652 // OpenCurrentProcessToken opens an access token associated with current
    653 // process with TOKEN_QUERY access. It is a real token that needs to be closed.
    654 //
    655 // Deprecated: Explicitly call OpenProcessToken(CurrentProcess(), ...)
    656 // with the desired access instead, or use GetCurrentProcessToken for a
    657 // TOKEN_QUERY token.
    658 func OpenCurrentProcessToken() (Token, error) {
    659 	var token Token
    660 	err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token)
    661 	return token, err
    662 }
    663 
    664 // GetCurrentProcessToken returns the access token associated with
    665 // the current process. It is a pseudo token that does not need
    666 // to be closed.
    667 func GetCurrentProcessToken() Token {
    668 	return Token(^uintptr(4 - 1))
    669 }
    670 
    671 // GetCurrentThreadToken return the access token associated with
    672 // the current thread. It is a pseudo token that does not need
    673 // to be closed.
    674 func GetCurrentThreadToken() Token {
    675 	return Token(^uintptr(5 - 1))
    676 }
    677 
    678 // GetCurrentThreadEffectiveToken returns the effective access token
    679 // associated with the current thread. It is a pseudo token that does
    680 // not need to be closed.
    681 func GetCurrentThreadEffectiveToken() Token {
    682 	return Token(^uintptr(6 - 1))
    683 }
    684 
    685 // Close releases access to access token.
    686 func (t Token) Close() error {
    687 	return CloseHandle(Handle(t))
    688 }
    689 
    690 // getInfo retrieves a specified type of information about an access token.
    691 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
    692 	n := uint32(initSize)
    693 	for {
    694 		b := make([]byte, n)
    695 		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
    696 		if e == nil {
    697 			return unsafe.Pointer(&b[0]), nil
    698 		}
    699 		if e != ERROR_INSUFFICIENT_BUFFER {
    700 			return nil, e
    701 		}
    702 		if n <= uint32(len(b)) {
    703 			return nil, e
    704 		}
    705 	}
    706 }
    707 
    708 // GetTokenUser retrieves access token t user account information.
    709 func (t Token) GetTokenUser() (*Tokenuser, error) {
    710 	i, e := t.getInfo(TokenUser, 50)
    711 	if e != nil {
    712 		return nil, e
    713 	}
    714 	return (*Tokenuser)(i), nil
    715 }
    716 
    717 // GetTokenGroups retrieves group accounts associated with access token t.
    718 func (t Token) GetTokenGroups() (*Tokengroups, error) {
    719 	i, e := t.getInfo(TokenGroups, 50)
    720 	if e != nil {
    721 		return nil, e
    722 	}
    723 	return (*Tokengroups)(i), nil
    724 }
    725 
    726 // GetTokenPrimaryGroup retrieves access token t primary group information.
    727 // A pointer to a SID structure representing a group that will become
    728 // the primary group of any objects created by a process using this access token.
    729 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
    730 	i, e := t.getInfo(TokenPrimaryGroup, 50)
    731 	if e != nil {
    732 		return nil, e
    733 	}
    734 	return (*Tokenprimarygroup)(i), nil
    735 }
    736 
    737 // GetUserProfileDirectory retrieves path to the
    738 // root directory of the access token t user's profile.
    739 func (t Token) GetUserProfileDirectory() (string, error) {
    740 	n := uint32(100)
    741 	for {
    742 		b := make([]uint16, n)
    743 		e := GetUserProfileDirectory(t, &b[0], &n)
    744 		if e == nil {
    745 			return UTF16ToString(b), nil
    746 		}
    747 		if e != ERROR_INSUFFICIENT_BUFFER {
    748 			return "", e
    749 		}
    750 		if n <= uint32(len(b)) {
    751 			return "", e
    752 		}
    753 	}
    754 }
    755 
    756 // IsElevated returns whether the current token is elevated from a UAC perspective.
    757 func (token Token) IsElevated() bool {
    758 	var isElevated uint32
    759 	var outLen uint32
    760 	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
    761 	if err != nil {
    762 		return false
    763 	}
    764 	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
    765 }
    766 
    767 // GetLinkedToken returns the linked token, which may be an elevated UAC token.
    768 func (token Token) GetLinkedToken() (Token, error) {
    769 	var linkedToken Token
    770 	var outLen uint32
    771 	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
    772 	if err != nil {
    773 		return Token(0), err
    774 	}
    775 	return linkedToken, nil
    776 }
    777 
    778 // GetSystemDirectory retrieves the path to current location of the system
    779 // directory, which is typically, though not always, `C:\Windows\System32`.
    780 func GetSystemDirectory() (string, error) {
    781 	n := uint32(MAX_PATH)
    782 	for {
    783 		b := make([]uint16, n)
    784 		l, e := getSystemDirectory(&b[0], n)
    785 		if e != nil {
    786 			return "", e
    787 		}
    788 		if l <= n {
    789 			return UTF16ToString(b[:l]), nil
    790 		}
    791 		n = l
    792 	}
    793 }
    794 
    795 // GetWindowsDirectory retrieves the path to current location of the Windows
    796 // directory, which is typically, though not always, `C:\Windows`. This may
    797 // be a private user directory in the case that the application is running
    798 // under a terminal server.
    799 func GetWindowsDirectory() (string, error) {
    800 	n := uint32(MAX_PATH)
    801 	for {
    802 		b := make([]uint16, n)
    803 		l, e := getWindowsDirectory(&b[0], n)
    804 		if e != nil {
    805 			return "", e
    806 		}
    807 		if l <= n {
    808 			return UTF16ToString(b[:l]), nil
    809 		}
    810 		n = l
    811 	}
    812 }
    813 
    814 // GetSystemWindowsDirectory retrieves the path to current location of the
    815 // Windows directory, which is typically, though not always, `C:\Windows`.
    816 func GetSystemWindowsDirectory() (string, error) {
    817 	n := uint32(MAX_PATH)
    818 	for {
    819 		b := make([]uint16, n)
    820 		l, e := getSystemWindowsDirectory(&b[0], n)
    821 		if e != nil {
    822 			return "", e
    823 		}
    824 		if l <= n {
    825 			return UTF16ToString(b[:l]), nil
    826 		}
    827 		n = l
    828 	}
    829 }
    830 
    831 // IsMember reports whether the access token t is a member of the provided SID.
    832 func (t Token) IsMember(sid *SID) (bool, error) {
    833 	var b int32
    834 	if e := checkTokenMembership(t, sid, &b); e != nil {
    835 		return false, e
    836 	}
    837 	return b != 0, nil
    838 }
    839 
    840 const (
    841 	WTS_CONSOLE_CONNECT        = 0x1
    842 	WTS_CONSOLE_DISCONNECT     = 0x2
    843 	WTS_REMOTE_CONNECT         = 0x3
    844 	WTS_REMOTE_DISCONNECT      = 0x4
    845 	WTS_SESSION_LOGON          = 0x5
    846 	WTS_SESSION_LOGOFF         = 0x6
    847 	WTS_SESSION_LOCK           = 0x7
    848 	WTS_SESSION_UNLOCK         = 0x8
    849 	WTS_SESSION_REMOTE_CONTROL = 0x9
    850 	WTS_SESSION_CREATE         = 0xa
    851 	WTS_SESSION_TERMINATE      = 0xb
    852 )
    853 
    854 const (
    855 	WTSActive       = 0
    856 	WTSConnected    = 1
    857 	WTSConnectQuery = 2
    858 	WTSShadow       = 3
    859 	WTSDisconnected = 4
    860 	WTSIdle         = 5
    861 	WTSListen       = 6
    862 	WTSReset        = 7
    863 	WTSDown         = 8
    864 	WTSInit         = 9
    865 )
    866 
    867 type WTSSESSION_NOTIFICATION struct {
    868 	Size      uint32
    869 	SessionID uint32
    870 }
    871 
    872 type WTS_SESSION_INFO struct {
    873 	SessionID         uint32
    874 	WindowStationName *uint16
    875 	State             uint32
    876 }
    877 
    878 //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
    879 //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
    880 //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
    881 
    882 type ACL struct {
    883 	aclRevision byte
    884 	sbz1        byte
    885 	aclSize     uint16
    886 	aceCount    uint16
    887 	sbz2        uint16
    888 }
    889 
    890 type SECURITY_DESCRIPTOR struct {
    891 	revision byte
    892 	sbz1     byte
    893 	control  SECURITY_DESCRIPTOR_CONTROL
    894 	owner    *SID
    895 	group    *SID
    896 	sacl     *ACL
    897 	dacl     *ACL
    898 }
    899 
    900 type SecurityAttributes struct {
    901 	Length             uint32
    902 	SecurityDescriptor *SECURITY_DESCRIPTOR
    903 	InheritHandle      uint32
    904 }
    905 
    906 type SE_OBJECT_TYPE uint32
    907 
    908 // Constants for type SE_OBJECT_TYPE
    909 const (
    910 	SE_UNKNOWN_OBJECT_TYPE     = 0
    911 	SE_FILE_OBJECT             = 1
    912 	SE_SERVICE                 = 2
    913 	SE_PRINTER                 = 3
    914 	SE_REGISTRY_KEY            = 4
    915 	SE_LMSHARE                 = 5
    916 	SE_KERNEL_OBJECT           = 6
    917 	SE_WINDOW_OBJECT           = 7
    918 	SE_DS_OBJECT               = 8
    919 	SE_DS_OBJECT_ALL           = 9
    920 	SE_PROVIDER_DEFINED_OBJECT = 10
    921 	SE_WMIGUID_OBJECT          = 11
    922 	SE_REGISTRY_WOW64_32KEY    = 12
    923 	SE_REGISTRY_WOW64_64KEY    = 13
    924 )
    925 
    926 type SECURITY_INFORMATION uint32
    927 
    928 // Constants for type SECURITY_INFORMATION
    929 const (
    930 	OWNER_SECURITY_INFORMATION            = 0x00000001
    931 	GROUP_SECURITY_INFORMATION            = 0x00000002
    932 	DACL_SECURITY_INFORMATION             = 0x00000004
    933 	SACL_SECURITY_INFORMATION             = 0x00000008
    934 	LABEL_SECURITY_INFORMATION            = 0x00000010
    935 	ATTRIBUTE_SECURITY_INFORMATION        = 0x00000020
    936 	SCOPE_SECURITY_INFORMATION            = 0x00000040
    937 	BACKUP_SECURITY_INFORMATION           = 0x00010000
    938 	PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000
    939 	PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000
    940 	UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
    941 	UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
    942 )
    943 
    944 type SECURITY_DESCRIPTOR_CONTROL uint16
    945 
    946 // Constants for type SECURITY_DESCRIPTOR_CONTROL
    947 const (
    948 	SE_OWNER_DEFAULTED       = 0x0001
    949 	SE_GROUP_DEFAULTED       = 0x0002
    950 	SE_DACL_PRESENT          = 0x0004
    951 	SE_DACL_DEFAULTED        = 0x0008
    952 	SE_SACL_PRESENT          = 0x0010
    953 	SE_SACL_DEFAULTED        = 0x0020
    954 	SE_DACL_AUTO_INHERIT_REQ = 0x0100
    955 	SE_SACL_AUTO_INHERIT_REQ = 0x0200
    956 	SE_DACL_AUTO_INHERITED   = 0x0400
    957 	SE_SACL_AUTO_INHERITED   = 0x0800
    958 	SE_DACL_PROTECTED        = 0x1000
    959 	SE_SACL_PROTECTED        = 0x2000
    960 	SE_RM_CONTROL_VALID      = 0x4000
    961 	SE_SELF_RELATIVE         = 0x8000
    962 )
    963 
    964 type ACCESS_MASK uint32
    965 
    966 // Constants for type ACCESS_MASK
    967 const (
    968 	DELETE                   = 0x00010000
    969 	READ_CONTROL             = 0x00020000
    970 	WRITE_DAC                = 0x00040000
    971 	WRITE_OWNER              = 0x00080000
    972 	SYNCHRONIZE              = 0x00100000
    973 	STANDARD_RIGHTS_REQUIRED = 0x000F0000
    974 	STANDARD_RIGHTS_READ     = READ_CONTROL
    975 	STANDARD_RIGHTS_WRITE    = READ_CONTROL
    976 	STANDARD_RIGHTS_EXECUTE  = READ_CONTROL
    977 	STANDARD_RIGHTS_ALL      = 0x001F0000
    978 	SPECIFIC_RIGHTS_ALL      = 0x0000FFFF
    979 	ACCESS_SYSTEM_SECURITY   = 0x01000000
    980 	MAXIMUM_ALLOWED          = 0x02000000
    981 	GENERIC_READ             = 0x80000000
    982 	GENERIC_WRITE            = 0x40000000
    983 	GENERIC_EXECUTE          = 0x20000000
    984 	GENERIC_ALL              = 0x10000000
    985 )
    986 
    987 type ACCESS_MODE uint32
    988 
    989 // Constants for type ACCESS_MODE
    990 const (
    991 	NOT_USED_ACCESS   = 0
    992 	GRANT_ACCESS      = 1
    993 	SET_ACCESS        = 2
    994 	DENY_ACCESS       = 3
    995 	REVOKE_ACCESS     = 4
    996 	SET_AUDIT_SUCCESS = 5
    997 	SET_AUDIT_FAILURE = 6
    998 )
    999 
   1000 // Constants for AceFlags and Inheritance fields
   1001 const (
   1002 	NO_INHERITANCE                     = 0x0
   1003 	SUB_OBJECTS_ONLY_INHERIT           = 0x1
   1004 	SUB_CONTAINERS_ONLY_INHERIT        = 0x2
   1005 	SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3
   1006 	INHERIT_NO_PROPAGATE               = 0x4
   1007 	INHERIT_ONLY                       = 0x8
   1008 	INHERITED_ACCESS_ENTRY             = 0x10
   1009 	INHERITED_PARENT                   = 0x10000000
   1010 	INHERITED_GRANDPARENT              = 0x20000000
   1011 	OBJECT_INHERIT_ACE                 = 0x1
   1012 	CONTAINER_INHERIT_ACE              = 0x2
   1013 	NO_PROPAGATE_INHERIT_ACE           = 0x4
   1014 	INHERIT_ONLY_ACE                   = 0x8
   1015 	INHERITED_ACE                      = 0x10
   1016 	VALID_INHERIT_FLAGS                = 0x1F
   1017 )
   1018 
   1019 type MULTIPLE_TRUSTEE_OPERATION uint32
   1020 
   1021 // Constants for MULTIPLE_TRUSTEE_OPERATION
   1022 const (
   1023 	NO_MULTIPLE_TRUSTEE    = 0
   1024 	TRUSTEE_IS_IMPERSONATE = 1
   1025 )
   1026 
   1027 type TRUSTEE_FORM uint32
   1028 
   1029 // Constants for TRUSTEE_FORM
   1030 const (
   1031 	TRUSTEE_IS_SID              = 0
   1032 	TRUSTEE_IS_NAME             = 1
   1033 	TRUSTEE_BAD_FORM            = 2
   1034 	TRUSTEE_IS_OBJECTS_AND_SID  = 3
   1035 	TRUSTEE_IS_OBJECTS_AND_NAME = 4
   1036 )
   1037 
   1038 type TRUSTEE_TYPE uint32
   1039 
   1040 // Constants for TRUSTEE_TYPE
   1041 const (
   1042 	TRUSTEE_IS_UNKNOWN          = 0
   1043 	TRUSTEE_IS_USER             = 1
   1044 	TRUSTEE_IS_GROUP            = 2
   1045 	TRUSTEE_IS_DOMAIN           = 3
   1046 	TRUSTEE_IS_ALIAS            = 4
   1047 	TRUSTEE_IS_WELL_KNOWN_GROUP = 5
   1048 	TRUSTEE_IS_DELETED          = 6
   1049 	TRUSTEE_IS_INVALID          = 7
   1050 	TRUSTEE_IS_COMPUTER         = 8
   1051 )
   1052 
   1053 // Constants for ObjectsPresent field
   1054 const (
   1055 	ACE_OBJECT_TYPE_PRESENT           = 0x1
   1056 	ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
   1057 )
   1058 
   1059 type EXPLICIT_ACCESS struct {
   1060 	AccessPermissions ACCESS_MASK
   1061 	AccessMode        ACCESS_MODE
   1062 	Inheritance       uint32
   1063 	Trustee           TRUSTEE
   1064 }
   1065 
   1066 // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
   1067 type TrusteeValue uintptr
   1068 
   1069 func TrusteeValueFromString(str string) TrusteeValue {
   1070 	return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
   1071 }
   1072 func TrusteeValueFromSID(sid *SID) TrusteeValue {
   1073 	return TrusteeValue(unsafe.Pointer(sid))
   1074 }
   1075 func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
   1076 	return TrusteeValue(unsafe.Pointer(objectsAndSid))
   1077 }
   1078 func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
   1079 	return TrusteeValue(unsafe.Pointer(objectsAndName))
   1080 }
   1081 
   1082 type TRUSTEE struct {
   1083 	MultipleTrustee          *TRUSTEE
   1084 	MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
   1085 	TrusteeForm              TRUSTEE_FORM
   1086 	TrusteeType              TRUSTEE_TYPE
   1087 	TrusteeValue             TrusteeValue
   1088 }
   1089 
   1090 type OBJECTS_AND_SID struct {
   1091 	ObjectsPresent          uint32
   1092 	ObjectTypeGuid          GUID
   1093 	InheritedObjectTypeGuid GUID
   1094 	Sid                     *SID
   1095 }
   1096 
   1097 type OBJECTS_AND_NAME struct {
   1098 	ObjectsPresent          uint32
   1099 	ObjectType              SE_OBJECT_TYPE
   1100 	ObjectTypeName          *uint16
   1101 	InheritedObjectTypeName *uint16
   1102 	Name                    *uint16
   1103 }
   1104 
   1105 //sys	getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetSecurityInfo
   1106 //sys	SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) = advapi32.SetSecurityInfo
   1107 //sys	getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetNamedSecurityInfoW
   1108 //sys	SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
   1109 
   1110 //sys	buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) = advapi32.BuildSecurityDescriptorW
   1111 //sys	initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
   1112 
   1113 //sys	getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl
   1114 //sys	getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl
   1115 //sys	getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl
   1116 //sys	getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner
   1117 //sys	getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup
   1118 //sys	getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength
   1119 //sys	getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl
   1120 //sys	isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor
   1121 
   1122 //sys	setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl
   1123 //sys	setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
   1124 //sys	setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
   1125 //sys	setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner
   1126 //sys	setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup
   1127 //sys	setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl
   1128 
   1129 //sys	convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
   1130 //sys	convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
   1131 
   1132 //sys	makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) = advapi32.MakeAbsoluteSD
   1133 //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
   1134 
   1135 //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
   1136 
   1137 // Control returns the security descriptor control bits.
   1138 func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
   1139 	err = getSecurityDescriptorControl(sd, &control, &revision)
   1140 	return
   1141 }
   1142 
   1143 // SetControl sets the security descriptor control bits.
   1144 func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {
   1145 	return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)
   1146 }
   1147 
   1148 // RMControl returns the security descriptor resource manager control bits.
   1149 func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {
   1150 	err = getSecurityDescriptorRMControl(sd, &control)
   1151 	return
   1152 }
   1153 
   1154 // SetRMControl sets the security descriptor resource manager control bits.
   1155 func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {
   1156 	setSecurityDescriptorRMControl(sd, &rmControl)
   1157 }
   1158 
   1159 // DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil
   1160 // if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns
   1161 // ERROR_OBJECT_NOT_FOUND.
   1162 func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {
   1163 	var present bool
   1164 	err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)
   1165 	if !present {
   1166 		err = ERROR_OBJECT_NOT_FOUND
   1167 	}
   1168 	return
   1169 }
   1170 
   1171 // SetDACL sets the absolute security descriptor DACL.
   1172 func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {
   1173 	return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted)
   1174 }
   1175 
   1176 // SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil
   1177 // if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns
   1178 // ERROR_OBJECT_NOT_FOUND.
   1179 func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {
   1180 	var present bool
   1181 	err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)
   1182 	if !present {
   1183 		err = ERROR_OBJECT_NOT_FOUND
   1184 	}
   1185 	return
   1186 }
   1187 
   1188 // SetSACL sets the absolute security descriptor SACL.
   1189 func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {
   1190 	return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)
   1191 }
   1192 
   1193 // Owner returns the security descriptor owner and whether it was defaulted.
   1194 func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {
   1195 	err = getSecurityDescriptorOwner(sd, &owner, &defaulted)
   1196 	return
   1197 }
   1198 
   1199 // SetOwner sets the absolute security descriptor owner.
   1200 func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {
   1201 	return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)
   1202 }
   1203 
   1204 // Group returns the security descriptor group and whether it was defaulted.
   1205 func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {
   1206 	err = getSecurityDescriptorGroup(sd, &group, &defaulted)
   1207 	return
   1208 }
   1209 
   1210 // SetGroup sets the absolute security descriptor owner.
   1211 func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {
   1212 	return setSecurityDescriptorGroup(absoluteSD, group, defaulted)
   1213 }
   1214 
   1215 // Length returns the length of the security descriptor.
   1216 func (sd *SECURITY_DESCRIPTOR) Length() uint32 {
   1217 	return getSecurityDescriptorLength(sd)
   1218 }
   1219 
   1220 // IsValid returns whether the security descriptor is valid.
   1221 func (sd *SECURITY_DESCRIPTOR) IsValid() bool {
   1222 	return isValidSecurityDescriptor(sd)
   1223 }
   1224 
   1225 // String returns the SDDL form of the security descriptor, with a function signature that can be
   1226 // used with %v formatting directives.
   1227 func (sd *SECURITY_DESCRIPTOR) String() string {
   1228 	var sddl *uint16
   1229 	err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)
   1230 	if err != nil {
   1231 		return ""
   1232 	}
   1233 	defer LocalFree(Handle(unsafe.Pointer(sddl)))
   1234 	return UTF16PtrToString(sddl)
   1235 }
   1236 
   1237 // ToAbsolute converts a self-relative security descriptor into an absolute one.
   1238 func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1239 	control, _, err := selfRelativeSD.Control()
   1240 	if err != nil {
   1241 		return
   1242 	}
   1243 	if control&SE_SELF_RELATIVE == 0 {
   1244 		err = ERROR_INVALID_PARAMETER
   1245 		return
   1246 	}
   1247 	var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32
   1248 	err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,
   1249 		nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)
   1250 	switch err {
   1251 	case ERROR_INSUFFICIENT_BUFFER:
   1252 	case nil:
   1253 		// makeAbsoluteSD is expected to fail, but it succeeds.
   1254 		return nil, ERROR_INTERNAL_ERROR
   1255 	default:
   1256 		return nil, err
   1257 	}
   1258 	if absoluteSDSize > 0 {
   1259 		absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
   1260 	}
   1261 	var (
   1262 		dacl  *ACL
   1263 		sacl  *ACL
   1264 		owner *SID
   1265 		group *SID
   1266 	)
   1267 	if daclSize > 0 {
   1268 		dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
   1269 	}
   1270 	if saclSize > 0 {
   1271 		sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
   1272 	}
   1273 	if ownerSize > 0 {
   1274 		owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
   1275 	}
   1276 	if groupSize > 0 {
   1277 		group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
   1278 	}
   1279 	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
   1280 		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
   1281 	return
   1282 }
   1283 
   1284 // ToSelfRelative converts an absolute security descriptor into a self-relative one.
   1285 func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
   1286 	control, _, err := absoluteSD.Control()
   1287 	if err != nil {
   1288 		return
   1289 	}
   1290 	if control&SE_SELF_RELATIVE != 0 {
   1291 		err = ERROR_INVALID_PARAMETER
   1292 		return
   1293 	}
   1294 	var selfRelativeSDSize uint32
   1295 	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
   1296 	switch err {
   1297 	case ERROR_INSUFFICIENT_BUFFER:
   1298 	case nil:
   1299 		// makeSelfRelativeSD is expected to fail, but it succeeds.
   1300 		return nil, ERROR_INTERNAL_ERROR
   1301 	default:
   1302 		return nil, err
   1303 	}
   1304 	if selfRelativeSDSize > 0 {
   1305 		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
   1306 	}
   1307 	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
   1308 	return
   1309 }
   1310 
   1311 func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
   1312 	sdLen := (int)(selfRelativeSD.Length())
   1313 
   1314 	var src []byte
   1315 	h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
   1316 	h.Data = unsafe.Pointer(selfRelativeSD)
   1317 	h.Len = sdLen
   1318 	h.Cap = sdLen
   1319 
   1320 	dst := make([]byte, sdLen)
   1321 	copy(dst, src)
   1322 	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
   1323 }
   1324 
   1325 // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
   1326 // self-relative security descriptor object allocated on the Go heap.
   1327 func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
   1328 	var winHeapSD *SECURITY_DESCRIPTOR
   1329 	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
   1330 	if err != nil {
   1331 		return
   1332 	}
   1333 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1334 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1335 }
   1336 
   1337 // GetSecurityInfo queries the security information for a given handle and returns the self-relative security
   1338 // descriptor result on the Go heap.
   1339 func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1340 	var winHeapSD *SECURITY_DESCRIPTOR
   1341 	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1342 	if err != nil {
   1343 		return
   1344 	}
   1345 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1346 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1347 }
   1348 
   1349 // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
   1350 // descriptor result on the Go heap.
   1351 func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1352 	var winHeapSD *SECURITY_DESCRIPTOR
   1353 	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1354 	if err != nil {
   1355 		return
   1356 	}
   1357 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1358 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1359 }
   1360 
   1361 // BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
   1362 // prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
   1363 // result on the Go heap.
   1364 func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
   1365 	var winHeapSD *SECURITY_DESCRIPTOR
   1366 	var winHeapSDSize uint32
   1367 	var firstAccessEntry *EXPLICIT_ACCESS
   1368 	if len(accessEntries) > 0 {
   1369 		firstAccessEntry = &accessEntries[0]
   1370 	}
   1371 	var firstAuditEntry *EXPLICIT_ACCESS
   1372 	if len(auditEntries) > 0 {
   1373 		firstAuditEntry = &auditEntries[0]
   1374 	}
   1375 	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
   1376 	if err != nil {
   1377 		return
   1378 	}
   1379 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1380 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1381 }
   1382 
   1383 // NewSecurityDescriptor creates and initializes a new absolute security descriptor.
   1384 func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1385 	absoluteSD = &SECURITY_DESCRIPTOR{}
   1386 	err = initializeSecurityDescriptor(absoluteSD, 1)
   1387 	return
   1388 }
   1389 
   1390 // ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
   1391 // Both explicitEntries and mergedACL are optional and can be nil.
   1392 func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
   1393 	var firstExplicitEntry *EXPLICIT_ACCESS
   1394 	if len(explicitEntries) > 0 {
   1395 		firstExplicitEntry = &explicitEntries[0]
   1396 	}
   1397 	var winHeapACL *ACL
   1398 	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
   1399 	if err != nil {
   1400 		return
   1401 	}
   1402 	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
   1403 	aclBytes := make([]byte, winHeapACL.aclSize)
   1404 	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
   1405 	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
   1406 }