src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

security_windows.go (55826B)


      1 // Copyright 2012 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package windows
      6 
      7 import (
      8 	"syscall"
      9 	"unsafe"
     10 )
     11 
     12 const (
     13 	NameUnknown          = 0
     14 	NameFullyQualifiedDN = 1
     15 	NameSamCompatible    = 2
     16 	NameDisplay          = 3
     17 	NameUniqueId         = 6
     18 	NameCanonical        = 7
     19 	NameUserPrincipal    = 8
     20 	NameCanonicalEx      = 9
     21 	NameServicePrincipal = 10
     22 	NameDnsDomain        = 12
     23 )
     24 
     25 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
     26 // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
     27 //sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
     28 //sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
     29 
     30 // TranslateAccountName converts a directory service
     31 // object name from one format to another.
     32 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
     33 	u, e := UTF16PtrFromString(username)
     34 	if e != nil {
     35 		return "", e
     36 	}
     37 	n := uint32(50)
     38 	for {
     39 		b := make([]uint16, n)
     40 		e = TranslateName(u, from, to, &b[0], &n)
     41 		if e == nil {
     42 			return UTF16ToString(b[:n]), nil
     43 		}
     44 		if e != ERROR_INSUFFICIENT_BUFFER {
     45 			return "", e
     46 		}
     47 		if n <= uint32(len(b)) {
     48 			return "", e
     49 		}
     50 	}
     51 }
     52 
     53 const (
     54 	// do not reorder
     55 	NetSetupUnknownStatus = iota
     56 	NetSetupUnjoined
     57 	NetSetupWorkgroupName
     58 	NetSetupDomainName
     59 )
     60 
     61 type UserInfo10 struct {
     62 	Name       *uint16
     63 	Comment    *uint16
     64 	UsrComment *uint16
     65 	FullName   *uint16
     66 }
     67 
     68 //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
     69 //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
     70 //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
     71 //sys   NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum
     72 
     73 const (
     74 	// do not reorder
     75 	SidTypeUser = 1 + iota
     76 	SidTypeGroup
     77 	SidTypeDomain
     78 	SidTypeAlias
     79 	SidTypeWellKnownGroup
     80 	SidTypeDeletedAccount
     81 	SidTypeInvalid
     82 	SidTypeUnknown
     83 	SidTypeComputer
     84 	SidTypeLabel
     85 )
     86 
     87 type SidIdentifierAuthority struct {
     88 	Value [6]byte
     89 }
     90 
     91 var (
     92 	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
     93 	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
     94 	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
     95 	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
     96 	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
     97 	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
     98 	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
     99 )
    100 
    101 const (
    102 	SECURITY_NULL_RID                   = 0
    103 	SECURITY_WORLD_RID                  = 0
    104 	SECURITY_LOCAL_RID                  = 0
    105 	SECURITY_CREATOR_OWNER_RID          = 0
    106 	SECURITY_CREATOR_GROUP_RID          = 1
    107 	SECURITY_DIALUP_RID                 = 1
    108 	SECURITY_NETWORK_RID                = 2
    109 	SECURITY_BATCH_RID                  = 3
    110 	SECURITY_INTERACTIVE_RID            = 4
    111 	SECURITY_LOGON_IDS_RID              = 5
    112 	SECURITY_SERVICE_RID                = 6
    113 	SECURITY_LOCAL_SYSTEM_RID           = 18
    114 	SECURITY_BUILTIN_DOMAIN_RID         = 32
    115 	SECURITY_PRINCIPAL_SELF_RID         = 10
    116 	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
    117 	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
    118 	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
    119 	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
    120 	SECURITY_PROXY_RID                  = 0x8
    121 	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
    122 	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
    123 	SECURITY_AUTHENTICATED_USER_RID     = 0xb
    124 	SECURITY_RESTRICTED_CODE_RID        = 0xc
    125 	SECURITY_NT_NON_UNIQUE_RID          = 0x15
    126 )
    127 
    128 // Predefined domain-relative RIDs for local groups.
    129 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
    130 const (
    131 	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
    132 	DOMAIN_ALIAS_RID_USERS                          = 0x221
    133 	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
    134 	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
    135 	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
    136 	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
    137 	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
    138 	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
    139 	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
    140 	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
    141 	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
    142 	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
    143 	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
    144 	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
    145 	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
    146 	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
    147 	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
    148 	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
    149 	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
    150 	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
    151 	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
    152 	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
    153 	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
    154 	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
    155 	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
    156 )
    157 
    158 //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
    159 //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
    160 //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
    161 //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
    162 //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
    163 //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
    164 //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
    165 //sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
    166 //sys	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
    167 //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
    168 //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
    169 //sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
    170 //sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
    171 //sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
    172 //sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
    173 
    174 // The security identifier (SID) structure is a variable-length
    175 // structure used to uniquely identify users or groups.
    176 type SID struct{}
    177 
    178 // StringToSid converts a string-format security identifier
    179 // SID into a valid, functional SID.
    180 func StringToSid(s string) (*SID, error) {
    181 	var sid *SID
    182 	p, e := UTF16PtrFromString(s)
    183 	if e != nil {
    184 		return nil, e
    185 	}
    186 	e = ConvertStringSidToSid(p, &sid)
    187 	if e != nil {
    188 		return nil, e
    189 	}
    190 	defer LocalFree((Handle)(unsafe.Pointer(sid)))
    191 	return sid.Copy()
    192 }
    193 
    194 // LookupSID retrieves a security identifier SID for the account
    195 // and the name of the domain on which the account was found.
    196 // System specify target computer to search.
    197 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
    198 	if len(account) == 0 {
    199 		return nil, "", 0, syscall.EINVAL
    200 	}
    201 	acc, e := UTF16PtrFromString(account)
    202 	if e != nil {
    203 		return nil, "", 0, e
    204 	}
    205 	var sys *uint16
    206 	if len(system) > 0 {
    207 		sys, e = UTF16PtrFromString(system)
    208 		if e != nil {
    209 			return nil, "", 0, e
    210 		}
    211 	}
    212 	n := uint32(50)
    213 	dn := uint32(50)
    214 	for {
    215 		b := make([]byte, n)
    216 		db := make([]uint16, dn)
    217 		sid = (*SID)(unsafe.Pointer(&b[0]))
    218 		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
    219 		if e == nil {
    220 			return sid, UTF16ToString(db), accType, nil
    221 		}
    222 		if e != ERROR_INSUFFICIENT_BUFFER {
    223 			return nil, "", 0, e
    224 		}
    225 		if n <= uint32(len(b)) {
    226 			return nil, "", 0, e
    227 		}
    228 	}
    229 }
    230 
    231 // String converts SID to a string format suitable for display, storage, or transmission.
    232 func (sid *SID) String() string {
    233 	var s *uint16
    234 	e := ConvertSidToStringSid(sid, &s)
    235 	if e != nil {
    236 		return ""
    237 	}
    238 	defer LocalFree((Handle)(unsafe.Pointer(s)))
    239 	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:])
    240 }
    241 
    242 // Len returns the length, in bytes, of a valid security identifier SID.
    243 func (sid *SID) Len() int {
    244 	return int(GetLengthSid(sid))
    245 }
    246 
    247 // Copy creates a duplicate of security identifier SID.
    248 func (sid *SID) Copy() (*SID, error) {
    249 	b := make([]byte, sid.Len())
    250 	sid2 := (*SID)(unsafe.Pointer(&b[0]))
    251 	e := CopySid(uint32(len(b)), sid2, sid)
    252 	if e != nil {
    253 		return nil, e
    254 	}
    255 	return sid2, nil
    256 }
    257 
    258 // IdentifierAuthority returns the identifier authority of the SID.
    259 func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
    260 	return *getSidIdentifierAuthority(sid)
    261 }
    262 
    263 // SubAuthorityCount returns the number of sub-authorities in the SID.
    264 func (sid *SID) SubAuthorityCount() uint8 {
    265 	return *getSidSubAuthorityCount(sid)
    266 }
    267 
    268 // SubAuthority returns the sub-authority of the SID as specified by
    269 // the index, which must be less than sid.SubAuthorityCount().
    270 func (sid *SID) SubAuthority(idx uint32) uint32 {
    271 	if idx >= uint32(sid.SubAuthorityCount()) {
    272 		panic("sub-authority index out of range")
    273 	}
    274 	return *getSidSubAuthority(sid, idx)
    275 }
    276 
    277 // IsValid returns whether the SID has a valid revision and length.
    278 func (sid *SID) IsValid() bool {
    279 	return isValidSid(sid)
    280 }
    281 
    282 // Equals compares two SIDs for equality.
    283 func (sid *SID) Equals(sid2 *SID) bool {
    284 	return EqualSid(sid, sid2)
    285 }
    286 
    287 // IsWellKnown determines whether the SID matches the well-known sidType.
    288 func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
    289 	return isWellKnownSid(sid, sidType)
    290 }
    291 
    292 // LookupAccount retrieves the name of the account for this SID
    293 // and the name of the first domain on which this SID is found.
    294 // System specify target computer to search for.
    295 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
    296 	var sys *uint16
    297 	if len(system) > 0 {
    298 		sys, err = UTF16PtrFromString(system)
    299 		if err != nil {
    300 			return "", "", 0, err
    301 		}
    302 	}
    303 	n := uint32(50)
    304 	dn := uint32(50)
    305 	for {
    306 		b := make([]uint16, n)
    307 		db := make([]uint16, dn)
    308 		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
    309 		if e == nil {
    310 			return UTF16ToString(b), UTF16ToString(db), accType, nil
    311 		}
    312 		if e != ERROR_INSUFFICIENT_BUFFER {
    313 			return "", "", 0, e
    314 		}
    315 		if n <= uint32(len(b)) {
    316 			return "", "", 0, e
    317 		}
    318 	}
    319 }
    320 
    321 // Various types of pre-specified SIDs that can be synthesized and compared at runtime.
    322 type WELL_KNOWN_SID_TYPE uint32
    323 
    324 const (
    325 	WinNullSid                                    = 0
    326 	WinWorldSid                                   = 1
    327 	WinLocalSid                                   = 2
    328 	WinCreatorOwnerSid                            = 3
    329 	WinCreatorGroupSid                            = 4
    330 	WinCreatorOwnerServerSid                      = 5
    331 	WinCreatorGroupServerSid                      = 6
    332 	WinNtAuthoritySid                             = 7
    333 	WinDialupSid                                  = 8
    334 	WinNetworkSid                                 = 9
    335 	WinBatchSid                                   = 10
    336 	WinInteractiveSid                             = 11
    337 	WinServiceSid                                 = 12
    338 	WinAnonymousSid                               = 13
    339 	WinProxySid                                   = 14
    340 	WinEnterpriseControllersSid                   = 15
    341 	WinSelfSid                                    = 16
    342 	WinAuthenticatedUserSid                       = 17
    343 	WinRestrictedCodeSid                          = 18
    344 	WinTerminalServerSid                          = 19
    345 	WinRemoteLogonIdSid                           = 20
    346 	WinLogonIdsSid                                = 21
    347 	WinLocalSystemSid                             = 22
    348 	WinLocalServiceSid                            = 23
    349 	WinNetworkServiceSid                          = 24
    350 	WinBuiltinDomainSid                           = 25
    351 	WinBuiltinAdministratorsSid                   = 26
    352 	WinBuiltinUsersSid                            = 27
    353 	WinBuiltinGuestsSid                           = 28
    354 	WinBuiltinPowerUsersSid                       = 29
    355 	WinBuiltinAccountOperatorsSid                 = 30
    356 	WinBuiltinSystemOperatorsSid                  = 31
    357 	WinBuiltinPrintOperatorsSid                   = 32
    358 	WinBuiltinBackupOperatorsSid                  = 33
    359 	WinBuiltinReplicatorSid                       = 34
    360 	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
    361 	WinBuiltinRemoteDesktopUsersSid               = 36
    362 	WinBuiltinNetworkConfigurationOperatorsSid    = 37
    363 	WinAccountAdministratorSid                    = 38
    364 	WinAccountGuestSid                            = 39
    365 	WinAccountKrbtgtSid                           = 40
    366 	WinAccountDomainAdminsSid                     = 41
    367 	WinAccountDomainUsersSid                      = 42
    368 	WinAccountDomainGuestsSid                     = 43
    369 	WinAccountComputersSid                        = 44
    370 	WinAccountControllersSid                      = 45
    371 	WinAccountCertAdminsSid                       = 46
    372 	WinAccountSchemaAdminsSid                     = 47
    373 	WinAccountEnterpriseAdminsSid                 = 48
    374 	WinAccountPolicyAdminsSid                     = 49
    375 	WinAccountRasAndIasServersSid                 = 50
    376 	WinNTLMAuthenticationSid                      = 51
    377 	WinDigestAuthenticationSid                    = 52
    378 	WinSChannelAuthenticationSid                  = 53
    379 	WinThisOrganizationSid                        = 54
    380 	WinOtherOrganizationSid                       = 55
    381 	WinBuiltinIncomingForestTrustBuildersSid      = 56
    382 	WinBuiltinPerfMonitoringUsersSid              = 57
    383 	WinBuiltinPerfLoggingUsersSid                 = 58
    384 	WinBuiltinAuthorizationAccessSid              = 59
    385 	WinBuiltinTerminalServerLicenseServersSid     = 60
    386 	WinBuiltinDCOMUsersSid                        = 61
    387 	WinBuiltinIUsersSid                           = 62
    388 	WinIUserSid                                   = 63
    389 	WinBuiltinCryptoOperatorsSid                  = 64
    390 	WinUntrustedLabelSid                          = 65
    391 	WinLowLabelSid                                = 66
    392 	WinMediumLabelSid                             = 67
    393 	WinHighLabelSid                               = 68
    394 	WinSystemLabelSid                             = 69
    395 	WinWriteRestrictedCodeSid                     = 70
    396 	WinCreatorOwnerRightsSid                      = 71
    397 	WinCacheablePrincipalsGroupSid                = 72
    398 	WinNonCacheablePrincipalsGroupSid             = 73
    399 	WinEnterpriseReadonlyControllersSid           = 74
    400 	WinAccountReadonlyControllersSid              = 75
    401 	WinBuiltinEventLogReadersGroup                = 76
    402 	WinNewEnterpriseReadonlyControllersSid        = 77
    403 	WinBuiltinCertSvcDComAccessGroup              = 78
    404 	WinMediumPlusLabelSid                         = 79
    405 	WinLocalLogonSid                              = 80
    406 	WinConsoleLogonSid                            = 81
    407 	WinThisOrganizationCertificateSid             = 82
    408 	WinApplicationPackageAuthoritySid             = 83
    409 	WinBuiltinAnyPackageSid                       = 84
    410 	WinCapabilityInternetClientSid                = 85
    411 	WinCapabilityInternetClientServerSid          = 86
    412 	WinCapabilityPrivateNetworkClientServerSid    = 87
    413 	WinCapabilityPicturesLibrarySid               = 88
    414 	WinCapabilityVideosLibrarySid                 = 89
    415 	WinCapabilityMusicLibrarySid                  = 90
    416 	WinCapabilityDocumentsLibrarySid              = 91
    417 	WinCapabilitySharedUserCertificatesSid        = 92
    418 	WinCapabilityEnterpriseAuthenticationSid      = 93
    419 	WinCapabilityRemovableStorageSid              = 94
    420 	WinBuiltinRDSRemoteAccessServersSid           = 95
    421 	WinBuiltinRDSEndpointServersSid               = 96
    422 	WinBuiltinRDSManagementServersSid             = 97
    423 	WinUserModeDriversSid                         = 98
    424 	WinBuiltinHyperVAdminsSid                     = 99
    425 	WinAccountCloneableControllersSid             = 100
    426 	WinBuiltinAccessControlAssistanceOperatorsSid = 101
    427 	WinBuiltinRemoteManagementUsersSid            = 102
    428 	WinAuthenticationAuthorityAssertedSid         = 103
    429 	WinAuthenticationServiceAssertedSid           = 104
    430 	WinLocalAccountSid                            = 105
    431 	WinLocalAccountAndAdministratorSid            = 106
    432 	WinAccountProtectedUsersSid                   = 107
    433 	WinCapabilityAppointmentsSid                  = 108
    434 	WinCapabilityContactsSid                      = 109
    435 	WinAccountDefaultSystemManagedSid             = 110
    436 	WinBuiltinDefaultSystemManagedGroupSid        = 111
    437 	WinBuiltinStorageReplicaAdminsSid             = 112
    438 	WinAccountKeyAdminsSid                        = 113
    439 	WinAccountEnterpriseKeyAdminsSid              = 114
    440 	WinAuthenticationKeyTrustSid                  = 115
    441 	WinAuthenticationKeyPropertyMFASid            = 116
    442 	WinAuthenticationKeyPropertyAttestationSid    = 117
    443 	WinAuthenticationFreshKeyAuthSid              = 118
    444 	WinBuiltinDeviceOwnersSid                     = 119
    445 )
    446 
    447 // Creates a SID for a well-known predefined alias, generally using the constants of the form
    448 // Win*Sid, for the local machine.
    449 func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
    450 	return CreateWellKnownDomainSid(sidType, nil)
    451 }
    452 
    453 // Creates a SID for a well-known predefined alias, generally using the constants of the form
    454 // Win*Sid, for the domain specified by the domainSid parameter.
    455 func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
    456 	n := uint32(50)
    457 	for {
    458 		b := make([]byte, n)
    459 		sid := (*SID)(unsafe.Pointer(&b[0]))
    460 		err := createWellKnownSid(sidType, domainSid, sid, &n)
    461 		if err == nil {
    462 			return sid, nil
    463 		}
    464 		if err != ERROR_INSUFFICIENT_BUFFER {
    465 			return nil, err
    466 		}
    467 		if n <= uint32(len(b)) {
    468 			return nil, err
    469 		}
    470 	}
    471 }
    472 
    473 const (
    474 	// do not reorder
    475 	TOKEN_ASSIGN_PRIMARY = 1 << iota
    476 	TOKEN_DUPLICATE
    477 	TOKEN_IMPERSONATE
    478 	TOKEN_QUERY
    479 	TOKEN_QUERY_SOURCE
    480 	TOKEN_ADJUST_PRIVILEGES
    481 	TOKEN_ADJUST_GROUPS
    482 	TOKEN_ADJUST_DEFAULT
    483 	TOKEN_ADJUST_SESSIONID
    484 
    485 	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
    486 		TOKEN_ASSIGN_PRIMARY |
    487 		TOKEN_DUPLICATE |
    488 		TOKEN_IMPERSONATE |
    489 		TOKEN_QUERY |
    490 		TOKEN_QUERY_SOURCE |
    491 		TOKEN_ADJUST_PRIVILEGES |
    492 		TOKEN_ADJUST_GROUPS |
    493 		TOKEN_ADJUST_DEFAULT |
    494 		TOKEN_ADJUST_SESSIONID
    495 	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
    496 	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
    497 		TOKEN_ADJUST_PRIVILEGES |
    498 		TOKEN_ADJUST_GROUPS |
    499 		TOKEN_ADJUST_DEFAULT
    500 	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
    501 )
    502 
    503 const (
    504 	// do not reorder
    505 	TokenUser = 1 + iota
    506 	TokenGroups
    507 	TokenPrivileges
    508 	TokenOwner
    509 	TokenPrimaryGroup
    510 	TokenDefaultDacl
    511 	TokenSource
    512 	TokenType
    513 	TokenImpersonationLevel
    514 	TokenStatistics
    515 	TokenRestrictedSids
    516 	TokenSessionId
    517 	TokenGroupsAndPrivileges
    518 	TokenSessionReference
    519 	TokenSandBoxInert
    520 	TokenAuditPolicy
    521 	TokenOrigin
    522 	TokenElevationType
    523 	TokenLinkedToken
    524 	TokenElevation
    525 	TokenHasRestrictions
    526 	TokenAccessInformation
    527 	TokenVirtualizationAllowed
    528 	TokenVirtualizationEnabled
    529 	TokenIntegrityLevel
    530 	TokenUIAccess
    531 	TokenMandatoryPolicy
    532 	TokenLogonSid
    533 	MaxTokenInfoClass
    534 )
    535 
    536 // Group attributes inside of Tokengroups.Groups[i].Attributes
    537 const (
    538 	SE_GROUP_MANDATORY          = 0x00000001
    539 	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
    540 	SE_GROUP_ENABLED            = 0x00000004
    541 	SE_GROUP_OWNER              = 0x00000008
    542 	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
    543 	SE_GROUP_INTEGRITY          = 0x00000020
    544 	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
    545 	SE_GROUP_LOGON_ID           = 0xC0000000
    546 	SE_GROUP_RESOURCE           = 0x20000000
    547 	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
    548 )
    549 
    550 // Privilege attributes
    551 const (
    552 	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
    553 	SE_PRIVILEGE_ENABLED            = 0x00000002
    554 	SE_PRIVILEGE_REMOVED            = 0x00000004
    555 	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
    556 	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
    557 )
    558 
    559 // Token types
    560 const (
    561 	TokenPrimary       = 1
    562 	TokenImpersonation = 2
    563 )
    564 
    565 // Impersonation levels
    566 const (
    567 	SecurityAnonymous      = 0
    568 	SecurityIdentification = 1
    569 	SecurityImpersonation  = 2
    570 	SecurityDelegation     = 3
    571 )
    572 
    573 type LUID struct {
    574 	LowPart  uint32
    575 	HighPart int32
    576 }
    577 
    578 type LUIDAndAttributes struct {
    579 	Luid       LUID
    580 	Attributes uint32
    581 }
    582 
    583 type SIDAndAttributes struct {
    584 	Sid        *SID
    585 	Attributes uint32
    586 }
    587 
    588 type Tokenuser struct {
    589 	User SIDAndAttributes
    590 }
    591 
    592 type Tokenprimarygroup struct {
    593 	PrimaryGroup *SID
    594 }
    595 
    596 type Tokengroups struct {
    597 	GroupCount uint32
    598 	Groups     [1]SIDAndAttributes // Use AllGroups() for iterating.
    599 }
    600 
    601 // AllGroups returns a slice that can be used to iterate over the groups in g.
    602 func (g *Tokengroups) AllGroups() []SIDAndAttributes {
    603 	return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]
    604 }
    605 
    606 type Tokenprivileges struct {
    607 	PrivilegeCount uint32
    608 	Privileges     [1]LUIDAndAttributes // Use AllPrivileges() for iterating.
    609 }
    610 
    611 // AllPrivileges returns a slice that can be used to iterate over the privileges in p.
    612 func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {
    613 	return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]
    614 }
    615 
    616 type Tokenmandatorylabel struct {
    617 	Label SIDAndAttributes
    618 }
    619 
    620 func (tml *Tokenmandatorylabel) Size() uint32 {
    621 	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
    622 }
    623 
    624 // Authorization Functions
    625 //sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
    626 //sys	isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted
    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 // IsRestricted reports whether the access token t is a restricted token.
    841 func (t Token) IsRestricted() (isRestricted bool, err error) {
    842 	isRestricted, err = isTokenRestricted(t)
    843 	if !isRestricted && err == syscall.EINVAL {
    844 		// If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token.
    845 		err = nil
    846 	}
    847 	return
    848 }
    849 
    850 const (
    851 	WTS_CONSOLE_CONNECT        = 0x1
    852 	WTS_CONSOLE_DISCONNECT     = 0x2
    853 	WTS_REMOTE_CONNECT         = 0x3
    854 	WTS_REMOTE_DISCONNECT      = 0x4
    855 	WTS_SESSION_LOGON          = 0x5
    856 	WTS_SESSION_LOGOFF         = 0x6
    857 	WTS_SESSION_LOCK           = 0x7
    858 	WTS_SESSION_UNLOCK         = 0x8
    859 	WTS_SESSION_REMOTE_CONTROL = 0x9
    860 	WTS_SESSION_CREATE         = 0xa
    861 	WTS_SESSION_TERMINATE      = 0xb
    862 )
    863 
    864 const (
    865 	WTSActive       = 0
    866 	WTSConnected    = 1
    867 	WTSConnectQuery = 2
    868 	WTSShadow       = 3
    869 	WTSDisconnected = 4
    870 	WTSIdle         = 5
    871 	WTSListen       = 6
    872 	WTSReset        = 7
    873 	WTSDown         = 8
    874 	WTSInit         = 9
    875 )
    876 
    877 type WTSSESSION_NOTIFICATION struct {
    878 	Size      uint32
    879 	SessionID uint32
    880 }
    881 
    882 type WTS_SESSION_INFO struct {
    883 	SessionID         uint32
    884 	WindowStationName *uint16
    885 	State             uint32
    886 }
    887 
    888 //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
    889 //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
    890 //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
    891 //sys WTSGetActiveConsoleSessionId() (sessionID uint32)
    892 
    893 type ACL struct {
    894 	aclRevision byte
    895 	sbz1        byte
    896 	aclSize     uint16
    897 	AceCount    uint16
    898 	sbz2        uint16
    899 }
    900 
    901 type SECURITY_DESCRIPTOR struct {
    902 	revision byte
    903 	sbz1     byte
    904 	control  SECURITY_DESCRIPTOR_CONTROL
    905 	owner    *SID
    906 	group    *SID
    907 	sacl     *ACL
    908 	dacl     *ACL
    909 }
    910 
    911 type SECURITY_QUALITY_OF_SERVICE struct {
    912 	Length              uint32
    913 	ImpersonationLevel  uint32
    914 	ContextTrackingMode byte
    915 	EffectiveOnly       byte
    916 }
    917 
    918 // Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
    919 const (
    920 	SECURITY_STATIC_TRACKING  = 0
    921 	SECURITY_DYNAMIC_TRACKING = 1
    922 )
    923 
    924 type SecurityAttributes struct {
    925 	Length             uint32
    926 	SecurityDescriptor *SECURITY_DESCRIPTOR
    927 	InheritHandle      uint32
    928 }
    929 
    930 type SE_OBJECT_TYPE uint32
    931 
    932 // Constants for type SE_OBJECT_TYPE
    933 const (
    934 	SE_UNKNOWN_OBJECT_TYPE     = 0
    935 	SE_FILE_OBJECT             = 1
    936 	SE_SERVICE                 = 2
    937 	SE_PRINTER                 = 3
    938 	SE_REGISTRY_KEY            = 4
    939 	SE_LMSHARE                 = 5
    940 	SE_KERNEL_OBJECT           = 6
    941 	SE_WINDOW_OBJECT           = 7
    942 	SE_DS_OBJECT               = 8
    943 	SE_DS_OBJECT_ALL           = 9
    944 	SE_PROVIDER_DEFINED_OBJECT = 10
    945 	SE_WMIGUID_OBJECT          = 11
    946 	SE_REGISTRY_WOW64_32KEY    = 12
    947 	SE_REGISTRY_WOW64_64KEY    = 13
    948 )
    949 
    950 type SECURITY_INFORMATION uint32
    951 
    952 // Constants for type SECURITY_INFORMATION
    953 const (
    954 	OWNER_SECURITY_INFORMATION            = 0x00000001
    955 	GROUP_SECURITY_INFORMATION            = 0x00000002
    956 	DACL_SECURITY_INFORMATION             = 0x00000004
    957 	SACL_SECURITY_INFORMATION             = 0x00000008
    958 	LABEL_SECURITY_INFORMATION            = 0x00000010
    959 	ATTRIBUTE_SECURITY_INFORMATION        = 0x00000020
    960 	SCOPE_SECURITY_INFORMATION            = 0x00000040
    961 	BACKUP_SECURITY_INFORMATION           = 0x00010000
    962 	PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000
    963 	PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000
    964 	UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
    965 	UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
    966 )
    967 
    968 type SECURITY_DESCRIPTOR_CONTROL uint16
    969 
    970 // Constants for type SECURITY_DESCRIPTOR_CONTROL
    971 const (
    972 	SE_OWNER_DEFAULTED       = 0x0001
    973 	SE_GROUP_DEFAULTED       = 0x0002
    974 	SE_DACL_PRESENT          = 0x0004
    975 	SE_DACL_DEFAULTED        = 0x0008
    976 	SE_SACL_PRESENT          = 0x0010
    977 	SE_SACL_DEFAULTED        = 0x0020
    978 	SE_DACL_AUTO_INHERIT_REQ = 0x0100
    979 	SE_SACL_AUTO_INHERIT_REQ = 0x0200
    980 	SE_DACL_AUTO_INHERITED   = 0x0400
    981 	SE_SACL_AUTO_INHERITED   = 0x0800
    982 	SE_DACL_PROTECTED        = 0x1000
    983 	SE_SACL_PROTECTED        = 0x2000
    984 	SE_RM_CONTROL_VALID      = 0x4000
    985 	SE_SELF_RELATIVE         = 0x8000
    986 )
    987 
    988 type ACCESS_MASK uint32
    989 
    990 // Constants for type ACCESS_MASK
    991 const (
    992 	DELETE                   = 0x00010000
    993 	READ_CONTROL             = 0x00020000
    994 	WRITE_DAC                = 0x00040000
    995 	WRITE_OWNER              = 0x00080000
    996 	SYNCHRONIZE              = 0x00100000
    997 	STANDARD_RIGHTS_REQUIRED = 0x000F0000
    998 	STANDARD_RIGHTS_READ     = READ_CONTROL
    999 	STANDARD_RIGHTS_WRITE    = READ_CONTROL
   1000 	STANDARD_RIGHTS_EXECUTE  = READ_CONTROL
   1001 	STANDARD_RIGHTS_ALL      = 0x001F0000
   1002 	SPECIFIC_RIGHTS_ALL      = 0x0000FFFF
   1003 	ACCESS_SYSTEM_SECURITY   = 0x01000000
   1004 	MAXIMUM_ALLOWED          = 0x02000000
   1005 	GENERIC_READ             = 0x80000000
   1006 	GENERIC_WRITE            = 0x40000000
   1007 	GENERIC_EXECUTE          = 0x20000000
   1008 	GENERIC_ALL              = 0x10000000
   1009 )
   1010 
   1011 type ACCESS_MODE uint32
   1012 
   1013 // Constants for type ACCESS_MODE
   1014 const (
   1015 	NOT_USED_ACCESS   = 0
   1016 	GRANT_ACCESS      = 1
   1017 	SET_ACCESS        = 2
   1018 	DENY_ACCESS       = 3
   1019 	REVOKE_ACCESS     = 4
   1020 	SET_AUDIT_SUCCESS = 5
   1021 	SET_AUDIT_FAILURE = 6
   1022 )
   1023 
   1024 // Constants for AceFlags and Inheritance fields
   1025 const (
   1026 	NO_INHERITANCE                     = 0x0
   1027 	SUB_OBJECTS_ONLY_INHERIT           = 0x1
   1028 	SUB_CONTAINERS_ONLY_INHERIT        = 0x2
   1029 	SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3
   1030 	INHERIT_NO_PROPAGATE               = 0x4
   1031 	INHERIT_ONLY                       = 0x8
   1032 	INHERITED_ACCESS_ENTRY             = 0x10
   1033 	INHERITED_PARENT                   = 0x10000000
   1034 	INHERITED_GRANDPARENT              = 0x20000000
   1035 	OBJECT_INHERIT_ACE                 = 0x1
   1036 	CONTAINER_INHERIT_ACE              = 0x2
   1037 	NO_PROPAGATE_INHERIT_ACE           = 0x4
   1038 	INHERIT_ONLY_ACE                   = 0x8
   1039 	INHERITED_ACE                      = 0x10
   1040 	VALID_INHERIT_FLAGS                = 0x1F
   1041 )
   1042 
   1043 type MULTIPLE_TRUSTEE_OPERATION uint32
   1044 
   1045 // Constants for MULTIPLE_TRUSTEE_OPERATION
   1046 const (
   1047 	NO_MULTIPLE_TRUSTEE    = 0
   1048 	TRUSTEE_IS_IMPERSONATE = 1
   1049 )
   1050 
   1051 type TRUSTEE_FORM uint32
   1052 
   1053 // Constants for TRUSTEE_FORM
   1054 const (
   1055 	TRUSTEE_IS_SID              = 0
   1056 	TRUSTEE_IS_NAME             = 1
   1057 	TRUSTEE_BAD_FORM            = 2
   1058 	TRUSTEE_IS_OBJECTS_AND_SID  = 3
   1059 	TRUSTEE_IS_OBJECTS_AND_NAME = 4
   1060 )
   1061 
   1062 type TRUSTEE_TYPE uint32
   1063 
   1064 // Constants for TRUSTEE_TYPE
   1065 const (
   1066 	TRUSTEE_IS_UNKNOWN          = 0
   1067 	TRUSTEE_IS_USER             = 1
   1068 	TRUSTEE_IS_GROUP            = 2
   1069 	TRUSTEE_IS_DOMAIN           = 3
   1070 	TRUSTEE_IS_ALIAS            = 4
   1071 	TRUSTEE_IS_WELL_KNOWN_GROUP = 5
   1072 	TRUSTEE_IS_DELETED          = 6
   1073 	TRUSTEE_IS_INVALID          = 7
   1074 	TRUSTEE_IS_COMPUTER         = 8
   1075 )
   1076 
   1077 // Constants for ObjectsPresent field
   1078 const (
   1079 	ACE_OBJECT_TYPE_PRESENT           = 0x1
   1080 	ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
   1081 )
   1082 
   1083 type EXPLICIT_ACCESS struct {
   1084 	AccessPermissions ACCESS_MASK
   1085 	AccessMode        ACCESS_MODE
   1086 	Inheritance       uint32
   1087 	Trustee           TRUSTEE
   1088 }
   1089 
   1090 // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
   1091 type ACE_HEADER struct {
   1092 	AceType  uint8
   1093 	AceFlags uint8
   1094 	AceSize  uint16
   1095 }
   1096 
   1097 // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
   1098 type ACCESS_ALLOWED_ACE struct {
   1099 	Header   ACE_HEADER
   1100 	Mask     ACCESS_MASK
   1101 	SidStart uint32
   1102 }
   1103 
   1104 const (
   1105 	// Constants for AceType
   1106 	// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
   1107 	ACCESS_ALLOWED_ACE_TYPE = 0
   1108 	ACCESS_DENIED_ACE_TYPE  = 1
   1109 )
   1110 
   1111 // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
   1112 type TrusteeValue uintptr
   1113 
   1114 func TrusteeValueFromString(str string) TrusteeValue {
   1115 	return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
   1116 }
   1117 func TrusteeValueFromSID(sid *SID) TrusteeValue {
   1118 	return TrusteeValue(unsafe.Pointer(sid))
   1119 }
   1120 func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
   1121 	return TrusteeValue(unsafe.Pointer(objectsAndSid))
   1122 }
   1123 func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
   1124 	return TrusteeValue(unsafe.Pointer(objectsAndName))
   1125 }
   1126 
   1127 type TRUSTEE struct {
   1128 	MultipleTrustee          *TRUSTEE
   1129 	MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
   1130 	TrusteeForm              TRUSTEE_FORM
   1131 	TrusteeType              TRUSTEE_TYPE
   1132 	TrusteeValue             TrusteeValue
   1133 }
   1134 
   1135 type OBJECTS_AND_SID struct {
   1136 	ObjectsPresent          uint32
   1137 	ObjectTypeGuid          GUID
   1138 	InheritedObjectTypeGuid GUID
   1139 	Sid                     *SID
   1140 }
   1141 
   1142 type OBJECTS_AND_NAME struct {
   1143 	ObjectsPresent          uint32
   1144 	ObjectType              SE_OBJECT_TYPE
   1145 	ObjectTypeName          *uint16
   1146 	InheritedObjectTypeName *uint16
   1147 	Name                    *uint16
   1148 }
   1149 
   1150 //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
   1151 //sys	SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo
   1152 //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
   1153 //sys	SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
   1154 //sys	SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity
   1155 
   1156 //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
   1157 //sys	initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
   1158 
   1159 //sys	getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl
   1160 //sys	getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl
   1161 //sys	getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl
   1162 //sys	getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner
   1163 //sys	getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup
   1164 //sys	getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength
   1165 //sys	getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl
   1166 //sys	isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor
   1167 
   1168 //sys	setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl
   1169 //sys	setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
   1170 //sys	setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
   1171 //sys	setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner
   1172 //sys	setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup
   1173 //sys	setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl
   1174 
   1175 //sys	convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
   1176 //sys	convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
   1177 
   1178 //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
   1179 //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
   1180 
   1181 //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
   1182 //sys	GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce
   1183 
   1184 // Control returns the security descriptor control bits.
   1185 func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
   1186 	err = getSecurityDescriptorControl(sd, &control, &revision)
   1187 	return
   1188 }
   1189 
   1190 // SetControl sets the security descriptor control bits.
   1191 func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {
   1192 	return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)
   1193 }
   1194 
   1195 // RMControl returns the security descriptor resource manager control bits.
   1196 func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {
   1197 	err = getSecurityDescriptorRMControl(sd, &control)
   1198 	return
   1199 }
   1200 
   1201 // SetRMControl sets the security descriptor resource manager control bits.
   1202 func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {
   1203 	setSecurityDescriptorRMControl(sd, &rmControl)
   1204 }
   1205 
   1206 // DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil
   1207 // if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns
   1208 // ERROR_OBJECT_NOT_FOUND.
   1209 func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {
   1210 	var present bool
   1211 	err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)
   1212 	if !present {
   1213 		err = ERROR_OBJECT_NOT_FOUND
   1214 	}
   1215 	return
   1216 }
   1217 
   1218 // SetDACL sets the absolute security descriptor DACL.
   1219 func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {
   1220 	return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted)
   1221 }
   1222 
   1223 // SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil
   1224 // if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns
   1225 // ERROR_OBJECT_NOT_FOUND.
   1226 func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {
   1227 	var present bool
   1228 	err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)
   1229 	if !present {
   1230 		err = ERROR_OBJECT_NOT_FOUND
   1231 	}
   1232 	return
   1233 }
   1234 
   1235 // SetSACL sets the absolute security descriptor SACL.
   1236 func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {
   1237 	return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)
   1238 }
   1239 
   1240 // Owner returns the security descriptor owner and whether it was defaulted.
   1241 func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {
   1242 	err = getSecurityDescriptorOwner(sd, &owner, &defaulted)
   1243 	return
   1244 }
   1245 
   1246 // SetOwner sets the absolute security descriptor owner.
   1247 func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {
   1248 	return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)
   1249 }
   1250 
   1251 // Group returns the security descriptor group and whether it was defaulted.
   1252 func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {
   1253 	err = getSecurityDescriptorGroup(sd, &group, &defaulted)
   1254 	return
   1255 }
   1256 
   1257 // SetGroup sets the absolute security descriptor owner.
   1258 func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {
   1259 	return setSecurityDescriptorGroup(absoluteSD, group, defaulted)
   1260 }
   1261 
   1262 // Length returns the length of the security descriptor.
   1263 func (sd *SECURITY_DESCRIPTOR) Length() uint32 {
   1264 	return getSecurityDescriptorLength(sd)
   1265 }
   1266 
   1267 // IsValid returns whether the security descriptor is valid.
   1268 func (sd *SECURITY_DESCRIPTOR) IsValid() bool {
   1269 	return isValidSecurityDescriptor(sd)
   1270 }
   1271 
   1272 // String returns the SDDL form of the security descriptor, with a function signature that can be
   1273 // used with %v formatting directives.
   1274 func (sd *SECURITY_DESCRIPTOR) String() string {
   1275 	var sddl *uint16
   1276 	err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)
   1277 	if err != nil {
   1278 		return ""
   1279 	}
   1280 	defer LocalFree(Handle(unsafe.Pointer(sddl)))
   1281 	return UTF16PtrToString(sddl)
   1282 }
   1283 
   1284 // ToAbsolute converts a self-relative security descriptor into an absolute one.
   1285 func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1286 	control, _, err := selfRelativeSD.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 absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32
   1295 	err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,
   1296 		nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)
   1297 	switch err {
   1298 	case ERROR_INSUFFICIENT_BUFFER:
   1299 	case nil:
   1300 		// makeAbsoluteSD is expected to fail, but it succeeds.
   1301 		return nil, ERROR_INTERNAL_ERROR
   1302 	default:
   1303 		return nil, err
   1304 	}
   1305 	if absoluteSDSize > 0 {
   1306 		absoluteSD = new(SECURITY_DESCRIPTOR)
   1307 		if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) {
   1308 			panic("sizeof(SECURITY_DESCRIPTOR) too small")
   1309 		}
   1310 	}
   1311 	var (
   1312 		dacl  *ACL
   1313 		sacl  *ACL
   1314 		owner *SID
   1315 		group *SID
   1316 	)
   1317 	if daclSize > 0 {
   1318 		dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize))))
   1319 	}
   1320 	if saclSize > 0 {
   1321 		sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize))))
   1322 	}
   1323 	if ownerSize > 0 {
   1324 		owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize))))
   1325 	}
   1326 	if groupSize > 0 {
   1327 		group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize))))
   1328 	}
   1329 	// We call into Windows via makeAbsoluteSD, which sets up
   1330 	// pointers within absoluteSD that point to other chunks of memory
   1331 	// we pass into makeAbsoluteSD, and that happens outside the view of the GC.
   1332 	// We therefore take some care here to then verify the pointers are as we expect
   1333 	// and set them explicitly in view of the GC. See https://go.dev/issue/73199.
   1334 	// TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575.
   1335 	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
   1336 		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
   1337 	if err != nil {
   1338 		// Don't return absoluteSD, which might be partially initialized.
   1339 		return nil, err
   1340 	}
   1341 	// Before using any fields, verify absoluteSD is in the format we expect according to Windows.
   1342 	// See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors
   1343 	absControl, _, err := absoluteSD.Control()
   1344 	if err != nil {
   1345 		panic("absoluteSD: " + err.Error())
   1346 	}
   1347 	if absControl&SE_SELF_RELATIVE != 0 {
   1348 		panic("absoluteSD not in absolute format")
   1349 	}
   1350 	if absoluteSD.dacl != dacl {
   1351 		panic("dacl pointer mismatch")
   1352 	}
   1353 	if absoluteSD.sacl != sacl {
   1354 		panic("sacl pointer mismatch")
   1355 	}
   1356 	if absoluteSD.owner != owner {
   1357 		panic("owner pointer mismatch")
   1358 	}
   1359 	if absoluteSD.group != group {
   1360 		panic("group pointer mismatch")
   1361 	}
   1362 	absoluteSD.dacl = dacl
   1363 	absoluteSD.sacl = sacl
   1364 	absoluteSD.owner = owner
   1365 	absoluteSD.group = group
   1366 
   1367 	return
   1368 }
   1369 
   1370 // ToSelfRelative converts an absolute security descriptor into a self-relative one.
   1371 func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
   1372 	control, _, err := absoluteSD.Control()
   1373 	if err != nil {
   1374 		return
   1375 	}
   1376 	if control&SE_SELF_RELATIVE != 0 {
   1377 		err = ERROR_INVALID_PARAMETER
   1378 		return
   1379 	}
   1380 	var selfRelativeSDSize uint32
   1381 	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
   1382 	switch err {
   1383 	case ERROR_INSUFFICIENT_BUFFER:
   1384 	case nil:
   1385 		// makeSelfRelativeSD is expected to fail, but it succeeds.
   1386 		return nil, ERROR_INTERNAL_ERROR
   1387 	default:
   1388 		return nil, err
   1389 	}
   1390 	if selfRelativeSDSize > 0 {
   1391 		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
   1392 	}
   1393 	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
   1394 	return
   1395 }
   1396 
   1397 func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
   1398 	sdLen := int(selfRelativeSD.Length())
   1399 	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
   1400 	if sdLen < min {
   1401 		sdLen = min
   1402 	}
   1403 
   1404 	src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen)
   1405 	// SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to
   1406 	// be aligned properly. When we're copying a Windows-allocated struct to a
   1407 	// Go-allocated one, make sure that the Go allocation is aligned to the
   1408 	// pointer size.
   1409 	const psize = int(unsafe.Sizeof(uintptr(0)))
   1410 	alloc := make([]uintptr, (sdLen+psize-1)/psize)
   1411 	dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen)
   1412 	copy(dst, src)
   1413 	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
   1414 }
   1415 
   1416 // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
   1417 // self-relative security descriptor object allocated on the Go heap.
   1418 func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
   1419 	var winHeapSD *SECURITY_DESCRIPTOR
   1420 	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
   1421 	if err != nil {
   1422 		return
   1423 	}
   1424 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1425 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1426 }
   1427 
   1428 // GetSecurityInfo queries the security information for a given handle and returns the self-relative security
   1429 // descriptor result on the Go heap.
   1430 func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1431 	var winHeapSD *SECURITY_DESCRIPTOR
   1432 	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1433 	if err != nil {
   1434 		return
   1435 	}
   1436 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1437 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1438 }
   1439 
   1440 // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
   1441 // descriptor result on the Go heap.
   1442 func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
   1443 	var winHeapSD *SECURITY_DESCRIPTOR
   1444 	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
   1445 	if err != nil {
   1446 		return
   1447 	}
   1448 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1449 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1450 }
   1451 
   1452 // BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
   1453 // prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
   1454 // result on the Go heap.
   1455 func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
   1456 	var winHeapSD *SECURITY_DESCRIPTOR
   1457 	var winHeapSDSize uint32
   1458 	var firstAccessEntry *EXPLICIT_ACCESS
   1459 	if len(accessEntries) > 0 {
   1460 		firstAccessEntry = &accessEntries[0]
   1461 	}
   1462 	var firstAuditEntry *EXPLICIT_ACCESS
   1463 	if len(auditEntries) > 0 {
   1464 		firstAuditEntry = &auditEntries[0]
   1465 	}
   1466 	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
   1467 	if err != nil {
   1468 		return
   1469 	}
   1470 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
   1471 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
   1472 }
   1473 
   1474 // NewSecurityDescriptor creates and initializes a new absolute security descriptor.
   1475 func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
   1476 	absoluteSD = &SECURITY_DESCRIPTOR{}
   1477 	err = initializeSecurityDescriptor(absoluteSD, 1)
   1478 	return
   1479 }
   1480 
   1481 // ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
   1482 // Both explicitEntries and mergedACL are optional and can be nil.
   1483 func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
   1484 	var firstExplicitEntry *EXPLICIT_ACCESS
   1485 	if len(explicitEntries) > 0 {
   1486 		firstExplicitEntry = &explicitEntries[0]
   1487 	}
   1488 	var winHeapACL *ACL
   1489 	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
   1490 	if err != nil {
   1491 		return
   1492 	}
   1493 	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
   1494 	aclBytes := make([]byte, winHeapACL.aclSize)
   1495 	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
   1496 	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
   1497 }