gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

security_windows.go (53493B)


      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	isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted
    628 //sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
    629 //sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
    630 //sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
    631 //sys	RevertToSelf() (err error) = advapi32.RevertToSelf
    632 //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
    633 //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
    634 //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
    635 //sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
    636 //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
    637 //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
    638 //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
    639 //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
    640 //sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
    641 //sys	getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW
    642 //sys	getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW
    643 
    644 // An access token contains the security information for a logon session.
    645 // The system creates an access token when a user logs on, and every
    646 // process executed on behalf of the user has a copy of the token.
    647 // The token identifies the user, the user's groups, and the user's
    648 // privileges. The system uses the token to control access to securable
    649 // objects and to control the ability of the user to perform various
    650 // system-related operations on the local computer.
    651 type Token Handle
    652 
    653 // OpenCurrentProcessToken opens an access token associated with current
    654 // process with TOKEN_QUERY access. It is a real token that needs to be closed.
    655 //
    656 // Deprecated: Explicitly call OpenProcessToken(CurrentProcess(), ...)
    657 // with the desired access instead, or use GetCurrentProcessToken for a
    658 // TOKEN_QUERY token.
    659 func OpenCurrentProcessToken() (Token, error) {
    660 	var token Token
    661 	err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token)
    662 	return token, err
    663 }
    664 
    665 // GetCurrentProcessToken returns the access token associated with
    666 // the current process. It is a pseudo token that does not need
    667 // to be closed.
    668 func GetCurrentProcessToken() Token {
    669 	return Token(^uintptr(4 - 1))
    670 }
    671 
    672 // GetCurrentThreadToken return the access token associated with
    673 // the current thread. It is a pseudo token that does not need
    674 // to be closed.
    675 func GetCurrentThreadToken() Token {
    676 	return Token(^uintptr(5 - 1))
    677 }
    678 
    679 // GetCurrentThreadEffectiveToken returns the effective access token
    680 // associated with the current thread. It is a pseudo token that does
    681 // not need to be closed.
    682 func GetCurrentThreadEffectiveToken() Token {
    683 	return Token(^uintptr(6 - 1))
    684 }
    685 
    686 // Close releases access to access token.
    687 func (t Token) Close() error {
    688 	return CloseHandle(Handle(t))
    689 }
    690 
    691 // getInfo retrieves a specified type of information about an access token.
    692 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
    693 	n := uint32(initSize)
    694 	for {
    695 		b := make([]byte, n)
    696 		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
    697 		if e == nil {
    698 			return unsafe.Pointer(&b[0]), nil
    699 		}
    700 		if e != ERROR_INSUFFICIENT_BUFFER {
    701 			return nil, e
    702 		}
    703 		if n <= uint32(len(b)) {
    704 			return nil, e
    705 		}
    706 	}
    707 }
    708 
    709 // GetTokenUser retrieves access token t user account information.
    710 func (t Token) GetTokenUser() (*Tokenuser, error) {
    711 	i, e := t.getInfo(TokenUser, 50)
    712 	if e != nil {
    713 		return nil, e
    714 	}
    715 	return (*Tokenuser)(i), nil
    716 }
    717 
    718 // GetTokenGroups retrieves group accounts associated with access token t.
    719 func (t Token) GetTokenGroups() (*Tokengroups, error) {
    720 	i, e := t.getInfo(TokenGroups, 50)
    721 	if e != nil {
    722 		return nil, e
    723 	}
    724 	return (*Tokengroups)(i), nil
    725 }
    726 
    727 // GetTokenPrimaryGroup retrieves access token t primary group information.
    728 // A pointer to a SID structure representing a group that will become
    729 // the primary group of any objects created by a process using this access token.
    730 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
    731 	i, e := t.getInfo(TokenPrimaryGroup, 50)
    732 	if e != nil {
    733 		return nil, e
    734 	}
    735 	return (*Tokenprimarygroup)(i), nil
    736 }
    737 
    738 // GetUserProfileDirectory retrieves path to the
    739 // root directory of the access token t user's profile.
    740 func (t Token) GetUserProfileDirectory() (string, error) {
    741 	n := uint32(100)
    742 	for {
    743 		b := make([]uint16, n)
    744 		e := GetUserProfileDirectory(t, &b[0], &n)
    745 		if e == nil {
    746 			return UTF16ToString(b), nil
    747 		}
    748 		if e != ERROR_INSUFFICIENT_BUFFER {
    749 			return "", e
    750 		}
    751 		if n <= uint32(len(b)) {
    752 			return "", e
    753 		}
    754 	}
    755 }
    756 
    757 // IsElevated returns whether the current token is elevated from a UAC perspective.
    758 func (token Token) IsElevated() bool {
    759 	var isElevated uint32
    760 	var outLen uint32
    761 	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
    762 	if err != nil {
    763 		return false
    764 	}
    765 	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
    766 }
    767 
    768 // GetLinkedToken returns the linked token, which may be an elevated UAC token.
    769 func (token Token) GetLinkedToken() (Token, error) {
    770 	var linkedToken Token
    771 	var outLen uint32
    772 	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
    773 	if err != nil {
    774 		return Token(0), err
    775 	}
    776 	return linkedToken, nil
    777 }
    778 
    779 // GetSystemDirectory retrieves the path to current location of the system
    780 // directory, which is typically, though not always, `C:\Windows\System32`.
    781 func GetSystemDirectory() (string, error) {
    782 	n := uint32(MAX_PATH)
    783 	for {
    784 		b := make([]uint16, n)
    785 		l, e := getSystemDirectory(&b[0], n)
    786 		if e != nil {
    787 			return "", e
    788 		}
    789 		if l <= n {
    790 			return UTF16ToString(b[:l]), nil
    791 		}
    792 		n = l
    793 	}
    794 }
    795 
    796 // GetWindowsDirectory retrieves the path to current location of the Windows
    797 // directory, which is typically, though not always, `C:\Windows`. This may
    798 // be a private user directory in the case that the application is running
    799 // under a terminal server.
    800 func GetWindowsDirectory() (string, error) {
    801 	n := uint32(MAX_PATH)
    802 	for {
    803 		b := make([]uint16, n)
    804 		l, e := getWindowsDirectory(&b[0], n)
    805 		if e != nil {
    806 			return "", e
    807 		}
    808 		if l <= n {
    809 			return UTF16ToString(b[:l]), nil
    810 		}
    811 		n = l
    812 	}
    813 }
    814 
    815 // GetSystemWindowsDirectory retrieves the path to current location of the
    816 // Windows directory, which is typically, though not always, `C:\Windows`.
    817 func GetSystemWindowsDirectory() (string, error) {
    818 	n := uint32(MAX_PATH)
    819 	for {
    820 		b := make([]uint16, n)
    821 		l, e := getSystemWindowsDirectory(&b[0], n)
    822 		if e != nil {
    823 			return "", e
    824 		}
    825 		if l <= n {
    826 			return UTF16ToString(b[:l]), nil
    827 		}
    828 		n = l
    829 	}
    830 }
    831 
    832 // IsMember reports whether the access token t is a member of the provided SID.
    833 func (t Token) IsMember(sid *SID) (bool, error) {
    834 	var b int32
    835 	if e := checkTokenMembership(t, sid, &b); e != nil {
    836 		return false, e
    837 	}
    838 	return b != 0, nil
    839 }
    840 
    841 // IsRestricted reports whether the access token t is a restricted token.
    842 func (t Token) IsRestricted() (isRestricted bool, err error) {
    843 	isRestricted, err = isTokenRestricted(t)
    844 	if !isRestricted && err == syscall.EINVAL {
    845 		// If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token.
    846 		err = nil
    847 	}
    848 	return
    849 }
    850 
    851 const (
    852 	WTS_CONSOLE_CONNECT        = 0x1
    853 	WTS_CONSOLE_DISCONNECT     = 0x2
    854 	WTS_REMOTE_CONNECT         = 0x3
    855 	WTS_REMOTE_DISCONNECT      = 0x4
    856 	WTS_SESSION_LOGON          = 0x5
    857 	WTS_SESSION_LOGOFF         = 0x6
    858 	WTS_SESSION_LOCK           = 0x7
    859 	WTS_SESSION_UNLOCK         = 0x8
    860 	WTS_SESSION_REMOTE_CONTROL = 0x9
    861 	WTS_SESSION_CREATE         = 0xa
    862 	WTS_SESSION_TERMINATE      = 0xb
    863 )
    864 
    865 const (
    866 	WTSActive       = 0
    867 	WTSConnected    = 1
    868 	WTSConnectQuery = 2
    869 	WTSShadow       = 3
    870 	WTSDisconnected = 4
    871 	WTSIdle         = 5
    872 	WTSListen       = 6
    873 	WTSReset        = 7
    874 	WTSDown         = 8
    875 	WTSInit         = 9
    876 )
    877 
    878 type WTSSESSION_NOTIFICATION struct {
    879 	Size      uint32
    880 	SessionID uint32
    881 }
    882 
    883 type WTS_SESSION_INFO struct {
    884 	SessionID         uint32
    885 	WindowStationName *uint16
    886 	State             uint32
    887 }
    888 
    889 //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
    890 //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
    891 //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
    892 //sys WTSGetActiveConsoleSessionId() (sessionID uint32)
    893 
    894 type ACL struct {
    895 	aclRevision byte
    896 	sbz1        byte
    897 	aclSize     uint16
    898 	aceCount    uint16
    899 	sbz2        uint16
    900 }
    901 
    902 type SECURITY_DESCRIPTOR struct {
    903 	revision byte
    904 	sbz1     byte
    905 	control  SECURITY_DESCRIPTOR_CONTROL
    906 	owner    *SID
    907 	group    *SID
    908 	sacl     *ACL
    909 	dacl     *ACL
    910 }
    911 
    912 type SECURITY_QUALITY_OF_SERVICE struct {
    913 	Length              uint32
    914 	ImpersonationLevel  uint32
    915 	ContextTrackingMode byte
    916 	EffectiveOnly       byte
    917 }
    918 
    919 // Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
    920 const (
    921 	SECURITY_STATIC_TRACKING  = 0
    922 	SECURITY_DYNAMIC_TRACKING = 1
    923 )
    924 
    925 type SecurityAttributes struct {
    926 	Length             uint32
    927 	SecurityDescriptor *SECURITY_DESCRIPTOR
    928 	InheritHandle      uint32
    929 }
    930 
    931 type SE_OBJECT_TYPE uint32
    932 
    933 // Constants for type SE_OBJECT_TYPE
    934 const (
    935 	SE_UNKNOWN_OBJECT_TYPE     = 0
    936 	SE_FILE_OBJECT             = 1
    937 	SE_SERVICE                 = 2
    938 	SE_PRINTER                 = 3
    939 	SE_REGISTRY_KEY            = 4
    940 	SE_LMSHARE                 = 5
    941 	SE_KERNEL_OBJECT           = 6
    942 	SE_WINDOW_OBJECT           = 7
    943 	SE_DS_OBJECT               = 8
    944 	SE_DS_OBJECT_ALL           = 9
    945 	SE_PROVIDER_DEFINED_OBJECT = 10
    946 	SE_WMIGUID_OBJECT          = 11
    947 	SE_REGISTRY_WOW64_32KEY    = 12
    948 	SE_REGISTRY_WOW64_64KEY    = 13
    949 )
    950 
    951 type SECURITY_INFORMATION uint32
    952 
    953 // Constants for type SECURITY_INFORMATION
    954 const (
    955 	OWNER_SECURITY_INFORMATION            = 0x00000001
    956 	GROUP_SECURITY_INFORMATION            = 0x00000002
    957 	DACL_SECURITY_INFORMATION             = 0x00000004
    958 	SACL_SECURITY_INFORMATION             = 0x00000008
    959 	LABEL_SECURITY_INFORMATION            = 0x00000010
    960 	ATTRIBUTE_SECURITY_INFORMATION        = 0x00000020
    961 	SCOPE_SECURITY_INFORMATION            = 0x00000040
    962 	BACKUP_SECURITY_INFORMATION           = 0x00010000
    963 	PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000
    964 	PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000
    965 	UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
    966 	UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
    967 )
    968 
    969 type SECURITY_DESCRIPTOR_CONTROL uint16
    970 
    971 // Constants for type SECURITY_DESCRIPTOR_CONTROL
    972 const (
    973 	SE_OWNER_DEFAULTED       = 0x0001
    974 	SE_GROUP_DEFAULTED       = 0x0002
    975 	SE_DACL_PRESENT          = 0x0004
    976 	SE_DACL_DEFAULTED        = 0x0008
    977 	SE_SACL_PRESENT          = 0x0010
    978 	SE_SACL_DEFAULTED        = 0x0020
    979 	SE_DACL_AUTO_INHERIT_REQ = 0x0100
    980 	SE_SACL_AUTO_INHERIT_REQ = 0x0200
    981 	SE_DACL_AUTO_INHERITED   = 0x0400
    982 	SE_SACL_AUTO_INHERITED   = 0x0800
    983 	SE_DACL_PROTECTED        = 0x1000
    984 	SE_SACL_PROTECTED        = 0x2000
    985 	SE_RM_CONTROL_VALID      = 0x4000
    986 	SE_SELF_RELATIVE         = 0x8000
    987 )
    988 
    989 type ACCESS_MASK uint32
    990 
    991 // Constants for type ACCESS_MASK
    992 const (
    993 	DELETE                   = 0x00010000
    994 	READ_CONTROL             = 0x00020000
    995 	WRITE_DAC                = 0x00040000
    996 	WRITE_OWNER              = 0x00080000
    997 	SYNCHRONIZE              = 0x00100000
    998 	STANDARD_RIGHTS_REQUIRED = 0x000F0000
    999 	STANDARD_RIGHTS_READ     = READ_CONTROL
   1000 	STANDARD_RIGHTS_WRITE    = READ_CONTROL
   1001 	STANDARD_RIGHTS_EXECUTE  = READ_CONTROL
   1002 	STANDARD_RIGHTS_ALL      = 0x001F0000
   1003 	SPECIFIC_RIGHTS_ALL      = 0x0000FFFF
   1004 	ACCESS_SYSTEM_SECURITY   = 0x01000000
   1005 	MAXIMUM_ALLOWED          = 0x02000000
   1006 	GENERIC_READ             = 0x80000000
   1007 	GENERIC_WRITE            = 0x40000000
   1008 	GENERIC_EXECUTE          = 0x20000000
   1009 	GENERIC_ALL              = 0x10000000
   1010 )
   1011 
   1012 type ACCESS_MODE uint32
   1013 
   1014 // Constants for type ACCESS_MODE
   1015 const (
   1016 	NOT_USED_ACCESS   = 0
   1017 	GRANT_ACCESS      = 1
   1018 	SET_ACCESS        = 2
   1019 	DENY_ACCESS       = 3
   1020 	REVOKE_ACCESS     = 4
   1021 	SET_AUDIT_SUCCESS = 5
   1022 	SET_AUDIT_FAILURE = 6
   1023 )
   1024 
   1025 // Constants for AceFlags and Inheritance fields
   1026 const (
   1027 	NO_INHERITANCE                     = 0x0
   1028 	SUB_OBJECTS_ONLY_INHERIT           = 0x1
   1029 	SUB_CONTAINERS_ONLY_INHERIT        = 0x2
   1030 	SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3
   1031 	INHERIT_NO_PROPAGATE               = 0x4
   1032 	INHERIT_ONLY                       = 0x8
   1033 	INHERITED_ACCESS_ENTRY             = 0x10
   1034 	INHERITED_PARENT                   = 0x10000000
   1035 	INHERITED_GRANDPARENT              = 0x20000000
   1036 	OBJECT_INHERIT_ACE                 = 0x1
   1037 	CONTAINER_INHERIT_ACE              = 0x2
   1038 	NO_PROPAGATE_INHERIT_ACE           = 0x4
   1039 	INHERIT_ONLY_ACE                   = 0x8
   1040 	INHERITED_ACE                      = 0x10
   1041 	VALID_INHERIT_FLAGS                = 0x1F
   1042 )
   1043 
   1044 type MULTIPLE_TRUSTEE_OPERATION uint32
   1045 
   1046 // Constants for MULTIPLE_TRUSTEE_OPERATION
   1047 const (
   1048 	NO_MULTIPLE_TRUSTEE    = 0
   1049 	TRUSTEE_IS_IMPERSONATE = 1
   1050 )
   1051 
   1052 type TRUSTEE_FORM uint32
   1053 
   1054 // Constants for TRUSTEE_FORM
   1055 const (
   1056 	TRUSTEE_IS_SID              = 0
   1057 	TRUSTEE_IS_NAME             = 1
   1058 	TRUSTEE_BAD_FORM            = 2
   1059 	TRUSTEE_IS_OBJECTS_AND_SID  = 3
   1060 	TRUSTEE_IS_OBJECTS_AND_NAME = 4
   1061 )
   1062 
   1063 type TRUSTEE_TYPE uint32
   1064 
   1065 // Constants for TRUSTEE_TYPE
   1066 const (
   1067 	TRUSTEE_IS_UNKNOWN          = 0
   1068 	TRUSTEE_IS_USER             = 1
   1069 	TRUSTEE_IS_GROUP            = 2
   1070 	TRUSTEE_IS_DOMAIN           = 3
   1071 	TRUSTEE_IS_ALIAS            = 4
   1072 	TRUSTEE_IS_WELL_KNOWN_GROUP = 5
   1073 	TRUSTEE_IS_DELETED          = 6
   1074 	TRUSTEE_IS_INVALID          = 7
   1075 	TRUSTEE_IS_COMPUTER         = 8
   1076 )
   1077 
   1078 // Constants for ObjectsPresent field
   1079 const (
   1080 	ACE_OBJECT_TYPE_PRESENT           = 0x1
   1081 	ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
   1082 )
   1083 
   1084 type EXPLICIT_ACCESS struct {
   1085 	AccessPermissions ACCESS_MASK
   1086 	AccessMode        ACCESS_MODE
   1087 	Inheritance       uint32
   1088 	Trustee           TRUSTEE
   1089 }
   1090 
   1091 // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
   1092 type TrusteeValue uintptr
   1093 
   1094 func TrusteeValueFromString(str string) TrusteeValue {
   1095 	return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
   1096 }
   1097 func TrusteeValueFromSID(sid *SID) TrusteeValue {
   1098 	return TrusteeValue(unsafe.Pointer(sid))
   1099 }
   1100 func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
   1101 	return TrusteeValue(unsafe.Pointer(objectsAndSid))
   1102 }
   1103 func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
   1104 	return TrusteeValue(unsafe.Pointer(objectsAndName))
   1105 }
   1106 
   1107 type TRUSTEE struct {
   1108 	MultipleTrustee          *TRUSTEE
   1109 	MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
   1110 	TrusteeForm              TRUSTEE_FORM
   1111 	TrusteeType              TRUSTEE_TYPE
   1112 	TrusteeValue             TrusteeValue
   1113 }
   1114 
   1115 type OBJECTS_AND_SID struct {
   1116 	ObjectsPresent          uint32
   1117 	ObjectTypeGuid          GUID
   1118 	InheritedObjectTypeGuid GUID
   1119 	Sid                     *SID
   1120 }
   1121 
   1122 type OBJECTS_AND_NAME struct {
   1123 	ObjectsPresent          uint32
   1124 	ObjectType              SE_OBJECT_TYPE
   1125 	ObjectTypeName          *uint16
   1126 	InheritedObjectTypeName *uint16
   1127 	Name                    *uint16
   1128 }
   1129 
   1130 //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
   1131 //sys	SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo
   1132 //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
   1133 //sys	SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
   1134 //sys	SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity
   1135 
   1136 //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
   1137 //sys	initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
   1138 
   1139 //sys	getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl
   1140 //sys	getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl
   1141 //sys	getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl
   1142 //sys	getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner
   1143 //sys	getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup
   1144 //sys	getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength
   1145 //sys	getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl
   1146 //sys	isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor
   1147 
   1148 //sys	setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl
   1149 //sys	setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
   1150 //sys	setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
   1151 //sys	setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner
   1152 //sys	setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup
   1153 //sys	setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl
   1154 
   1155 //sys	convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
   1156 //sys	convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
   1157 
   1158 //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
   1159 //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
   1160 
   1161 //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
   1162 
   1163 // Control returns the security descriptor control bits.
   1164 func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
   1165 	err = getSecurityDescriptorControl(sd, &control, &revision)
   1166 	return
   1167 }
   1168 
   1169 // SetControl sets the security descriptor control bits.
   1170 func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {
   1171 	return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)
   1172 }
   1173 
   1174 // RMControl returns the security descriptor resource manager control bits.
   1175 func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {
   1176 	err = getSecurityDescriptorRMControl(sd, &control)
   1177 	return
   1178 }
   1179 
   1180 // SetRMControl sets the security descriptor resource manager control bits.
   1181 func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {
   1182 	setSecurityDescriptorRMControl(sd, &rmControl)
   1183 }
   1184 
   1185 // DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil
   1186 // if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns
   1187 // ERROR_OBJECT_NOT_FOUND.
   1188 func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {
   1189 	var present bool
   1190 	err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)
   1191 	if !present {
   1192 		err = ERROR_OBJECT_NOT_FOUND
   1193 	}
   1194 	return
   1195 }
   1196 
   1197 // SetDACL sets the absolute security descriptor DACL.
   1198 func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {
   1199 	return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted)
   1200 }
   1201 
   1202 // SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil
   1203 // if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns
   1204 // ERROR_OBJECT_NOT_FOUND.
   1205 func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {
   1206 	var present bool
   1207 	err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)
   1208 	if !present {
   1209 		err = ERROR_OBJECT_NOT_FOUND
   1210 	}
   1211 	return
   1212 }
   1213 
   1214 // SetSACL sets the absolute security descriptor SACL.
   1215 func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {
   1216 	return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)
   1217 }
   1218 
   1219 // Owner returns the security descriptor owner and whether it was defaulted.
   1220 func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {
   1221 	err = getSecurityDescriptorOwner(sd, &owner, &defaulted)
   1222 	return
   1223 }
   1224 
   1225 // SetOwner sets the absolute security descriptor owner.
   1226 func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {
   1227 	return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)
   1228 }
   1229 
   1230 // Group returns the security descriptor group and whether it was defaulted.
   1231 func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {
   1232 	err = getSecurityDescriptorGroup(sd, &group, &defaulted)
   1233 	return
   1234 }
   1235 
   1236 // SetGroup sets the absolute security descriptor owner.
   1237 func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {
   1238 	return setSecurityDescriptorGroup(absoluteSD, group, defaulted)
   1239 }
   1240 
   1241 // Length returns the length of the security descriptor.
   1242 func (sd *SECURITY_DESCRIPTOR) Length() uint32 {
   1243 	return getSecurityDescriptorLength(sd)
   1244 }
   1245 
   1246 // IsValid returns whether the security descriptor is valid.
   1247 func (sd *SECURITY_DESCRIPTOR) IsValid() bool {
   1248 	return isValidSecurityDescriptor(sd)
   1249 }
   1250 
   1251 // String returns the SDDL form of the security descriptor, with a function signature that can be
   1252 // used with %v formatting directives.
   1253 func (sd *SECURITY_DESCRIPTOR) String() string {
   1254 	var sddl *uint16
   1255 	err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)
   1256 	if err != nil {
   1257 		return ""
   1258 	}
   1259 	defer LocalFree(Handle(unsafe.Pointer(sddl)))
   1260 	return UTF16PtrToString(sddl)
   1261 }
   1262 
   1263 // ToAbsolute converts a self-relative security descriptor into an absolute one.
   1264 func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1265 	control, _, err := selfRelativeSD.Control()
   1266 	if err != nil {
   1267 		return
   1268 	}
   1269 	if control&SE_SELF_RELATIVE == 0 {
   1270 		err = ERROR_INVALID_PARAMETER
   1271 		return
   1272 	}
   1273 	var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32
   1274 	err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,
   1275 		nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)
   1276 	switch err {
   1277 	case ERROR_INSUFFICIENT_BUFFER:
   1278 	case nil:
   1279 		// makeAbsoluteSD is expected to fail, but it succeeds.
   1280 		return nil, ERROR_INTERNAL_ERROR
   1281 	default:
   1282 		return nil, err
   1283 	}
   1284 	if absoluteSDSize > 0 {
   1285 		absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
   1286 	}
   1287 	var (
   1288 		dacl  *ACL
   1289 		sacl  *ACL
   1290 		owner *SID
   1291 		group *SID
   1292 	)
   1293 	if daclSize > 0 {
   1294 		dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
   1295 	}
   1296 	if saclSize > 0 {
   1297 		sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
   1298 	}
   1299 	if ownerSize > 0 {
   1300 		owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
   1301 	}
   1302 	if groupSize > 0 {
   1303 		group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
   1304 	}
   1305 	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
   1306 		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
   1307 	return
   1308 }
   1309 
   1310 // ToSelfRelative converts an absolute security descriptor into a self-relative one.
   1311 func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
   1312 	control, _, err := absoluteSD.Control()
   1313 	if err != nil {
   1314 		return
   1315 	}
   1316 	if control&SE_SELF_RELATIVE != 0 {
   1317 		err = ERROR_INVALID_PARAMETER
   1318 		return
   1319 	}
   1320 	var selfRelativeSDSize uint32
   1321 	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
   1322 	switch err {
   1323 	case ERROR_INSUFFICIENT_BUFFER:
   1324 	case nil:
   1325 		// makeSelfRelativeSD is expected to fail, but it succeeds.
   1326 		return nil, ERROR_INTERNAL_ERROR
   1327 	default:
   1328 		return nil, err
   1329 	}
   1330 	if selfRelativeSDSize > 0 {
   1331 		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
   1332 	}
   1333 	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
   1334 	return
   1335 }
   1336 
   1337 func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
   1338 	sdLen := int(selfRelativeSD.Length())
   1339 	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
   1340 	if sdLen < min {
   1341 		sdLen = min
   1342 	}
   1343 
   1344 	var src []byte
   1345 	h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
   1346 	h.Data = unsafe.Pointer(selfRelativeSD)
   1347 	h.Len = sdLen
   1348 	h.Cap = sdLen
   1349 
   1350 	const psize = int(unsafe.Sizeof(uintptr(0)))
   1351 
   1352 	var dst []byte
   1353 	h = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
   1354 	alloc := make([]uintptr, (sdLen+psize-1)/psize)
   1355 	h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data
   1356 	h.Len = sdLen
   1357 	h.Cap = sdLen
   1358 
   1359 	copy(dst, src)
   1360 	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
   1361 }
   1362 
   1363 // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
   1364 // self-relative security descriptor object allocated on the Go heap.
   1365 func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
   1366 	var winHeapSD *SECURITY_DESCRIPTOR
   1367 	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
   1368 	if err != nil {
   1369 		return
   1370 	}
   1371 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1372 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1373 }
   1374 
   1375 // GetSecurityInfo queries the security information for a given handle and returns the self-relative security
   1376 // descriptor result on the Go heap.
   1377 func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1378 	var winHeapSD *SECURITY_DESCRIPTOR
   1379 	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1380 	if err != nil {
   1381 		return
   1382 	}
   1383 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1384 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1385 }
   1386 
   1387 // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
   1388 // descriptor result on the Go heap.
   1389 func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1390 	var winHeapSD *SECURITY_DESCRIPTOR
   1391 	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1392 	if err != nil {
   1393 		return
   1394 	}
   1395 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1396 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1397 }
   1398 
   1399 // BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
   1400 // prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
   1401 // result on the Go heap.
   1402 func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
   1403 	var winHeapSD *SECURITY_DESCRIPTOR
   1404 	var winHeapSDSize uint32
   1405 	var firstAccessEntry *EXPLICIT_ACCESS
   1406 	if len(accessEntries) > 0 {
   1407 		firstAccessEntry = &accessEntries[0]
   1408 	}
   1409 	var firstAuditEntry *EXPLICIT_ACCESS
   1410 	if len(auditEntries) > 0 {
   1411 		firstAuditEntry = &auditEntries[0]
   1412 	}
   1413 	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
   1414 	if err != nil {
   1415 		return
   1416 	}
   1417 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1418 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1419 }
   1420 
   1421 // NewSecurityDescriptor creates and initializes a new absolute security descriptor.
   1422 func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1423 	absoluteSD = &SECURITY_DESCRIPTOR{}
   1424 	err = initializeSecurityDescriptor(absoluteSD, 1)
   1425 	return
   1426 }
   1427 
   1428 // ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
   1429 // Both explicitEntries and mergedACL are optional and can be nil.
   1430 func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
   1431 	var firstExplicitEntry *EXPLICIT_ACCESS
   1432 	if len(explicitEntries) > 0 {
   1433 		firstExplicitEntry = &explicitEntries[0]
   1434 	}
   1435 	var winHeapACL *ACL
   1436 	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
   1437 	if err != nil {
   1438 		return
   1439 	}
   1440 	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
   1441 	aclBytes := make([]byte, winHeapACL.aclSize)
   1442 	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
   1443 	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
   1444 }