security_windows.go raw

   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  }
1498