 e48bbe8394
			
		
	
	e48bbe8394
	
	
	
		
			
			In linux 5.14 and hopefully some backports, core scheduling allows processes to be co scheduled within the same domain on SMT enabled systems. The containerd impl sets the core sched domain when launching a shim. This allows a clean way for each shim(container/pod) to be in its own domain and any additional containers, (v2 pods) be be launched with the same domain as well as any exec'd process added to the container. kernel docs: https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/core-scheduling.html Signed-off-by: Michael Crosby <michael@thepasture.io>
		
			
				
	
	
		
			1445 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1445 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2012 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package windows
 | |
| 
 | |
| import (
 | |
| 	"syscall"
 | |
| 	"unsafe"
 | |
| 
 | |
| 	"golang.org/x/sys/internal/unsafeheader"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	NameUnknown          = 0
 | |
| 	NameFullyQualifiedDN = 1
 | |
| 	NameSamCompatible    = 2
 | |
| 	NameDisplay          = 3
 | |
| 	NameUniqueId         = 6
 | |
| 	NameCanonical        = 7
 | |
| 	NameUserPrincipal    = 8
 | |
| 	NameCanonicalEx      = 9
 | |
| 	NameServicePrincipal = 10
 | |
| 	NameDnsDomain        = 12
 | |
| )
 | |
| 
 | |
| // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
 | |
| // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
 | |
| //sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
 | |
| //sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
 | |
| 
 | |
| // TranslateAccountName converts a directory service
 | |
| // object name from one format to another.
 | |
| func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
 | |
| 	u, e := UTF16PtrFromString(username)
 | |
| 	if e != nil {
 | |
| 		return "", e
 | |
| 	}
 | |
| 	n := uint32(50)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		e = TranslateName(u, from, to, &b[0], &n)
 | |
| 		if e == nil {
 | |
| 			return UTF16ToString(b[:n]), nil
 | |
| 		}
 | |
| 		if e != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return "", e
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return "", e
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	// do not reorder
 | |
| 	NetSetupUnknownStatus = iota
 | |
| 	NetSetupUnjoined
 | |
| 	NetSetupWorkgroupName
 | |
| 	NetSetupDomainName
 | |
| )
 | |
| 
 | |
| type UserInfo10 struct {
 | |
| 	Name       *uint16
 | |
| 	Comment    *uint16
 | |
| 	UsrComment *uint16
 | |
| 	FullName   *uint16
 | |
| }
 | |
| 
 | |
| //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
 | |
| //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
 | |
| //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
 | |
| 
 | |
| const (
 | |
| 	// do not reorder
 | |
| 	SidTypeUser = 1 + iota
 | |
| 	SidTypeGroup
 | |
| 	SidTypeDomain
 | |
| 	SidTypeAlias
 | |
| 	SidTypeWellKnownGroup
 | |
| 	SidTypeDeletedAccount
 | |
| 	SidTypeInvalid
 | |
| 	SidTypeUnknown
 | |
| 	SidTypeComputer
 | |
| 	SidTypeLabel
 | |
| )
 | |
| 
 | |
| type SidIdentifierAuthority struct {
 | |
| 	Value [6]byte
 | |
| }
 | |
| 
 | |
| var (
 | |
| 	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
 | |
| 	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
 | |
| 	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
 | |
| 	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
 | |
| 	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
 | |
| 	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
 | |
| 	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	SECURITY_NULL_RID                   = 0
 | |
| 	SECURITY_WORLD_RID                  = 0
 | |
| 	SECURITY_LOCAL_RID                  = 0
 | |
| 	SECURITY_CREATOR_OWNER_RID          = 0
 | |
| 	SECURITY_CREATOR_GROUP_RID          = 1
 | |
| 	SECURITY_DIALUP_RID                 = 1
 | |
| 	SECURITY_NETWORK_RID                = 2
 | |
| 	SECURITY_BATCH_RID                  = 3
 | |
| 	SECURITY_INTERACTIVE_RID            = 4
 | |
| 	SECURITY_LOGON_IDS_RID              = 5
 | |
| 	SECURITY_SERVICE_RID                = 6
 | |
| 	SECURITY_LOCAL_SYSTEM_RID           = 18
 | |
| 	SECURITY_BUILTIN_DOMAIN_RID         = 32
 | |
| 	SECURITY_PRINCIPAL_SELF_RID         = 10
 | |
| 	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
 | |
| 	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
 | |
| 	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
 | |
| 	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
 | |
| 	SECURITY_PROXY_RID                  = 0x8
 | |
| 	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
 | |
| 	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
 | |
| 	SECURITY_AUTHENTICATED_USER_RID     = 0xb
 | |
| 	SECURITY_RESTRICTED_CODE_RID        = 0xc
 | |
| 	SECURITY_NT_NON_UNIQUE_RID          = 0x15
 | |
| )
 | |
| 
 | |
| // Predefined domain-relative RIDs for local groups.
 | |
| // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
 | |
| const (
 | |
| 	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
 | |
| 	DOMAIN_ALIAS_RID_USERS                          = 0x221
 | |
| 	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
 | |
| 	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
 | |
| 	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
 | |
| 	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
 | |
| 	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
 | |
| 	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
 | |
| 	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
 | |
| 	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
 | |
| 	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
 | |
| 	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
 | |
| 	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
 | |
| 	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
 | |
| 	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
 | |
| 	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
 | |
| 	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
 | |
| 	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
 | |
| 	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
 | |
| 	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
 | |
| 	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
 | |
| 	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
 | |
| 	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
 | |
| 	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
 | |
| 	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
 | |
| )
 | |
| 
 | |
| //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
 | |
| //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
 | |
| //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
 | |
| //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
 | |
| //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
 | |
| //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
 | |
| //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
 | |
| //sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
 | |
| //sys	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
 | |
| //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
 | |
| //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
 | |
| //sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
 | |
| //sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
 | |
| //sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
 | |
| //sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
 | |
| 
 | |
| // The security identifier (SID) structure is a variable-length
 | |
| // structure used to uniquely identify users or groups.
 | |
| type SID struct{}
 | |
| 
 | |
| // StringToSid converts a string-format security identifier
 | |
| // SID into a valid, functional SID.
 | |
| func StringToSid(s string) (*SID, error) {
 | |
| 	var sid *SID
 | |
| 	p, e := UTF16PtrFromString(s)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	e = ConvertStringSidToSid(p, &sid)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	defer LocalFree((Handle)(unsafe.Pointer(sid)))
 | |
| 	return sid.Copy()
 | |
| }
 | |
| 
 | |
| // LookupSID retrieves a security identifier SID for the account
 | |
| // and the name of the domain on which the account was found.
 | |
| // System specify target computer to search.
 | |
| func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
 | |
| 	if len(account) == 0 {
 | |
| 		return nil, "", 0, syscall.EINVAL
 | |
| 	}
 | |
| 	acc, e := UTF16PtrFromString(account)
 | |
| 	if e != nil {
 | |
| 		return nil, "", 0, e
 | |
| 	}
 | |
| 	var sys *uint16
 | |
| 	if len(system) > 0 {
 | |
| 		sys, e = UTF16PtrFromString(system)
 | |
| 		if e != nil {
 | |
| 			return nil, "", 0, e
 | |
| 		}
 | |
| 	}
 | |
| 	n := uint32(50)
 | |
| 	dn := uint32(50)
 | |
| 	for {
 | |
| 		b := make([]byte, n)
 | |
| 		db := make([]uint16, dn)
 | |
| 		sid = (*SID)(unsafe.Pointer(&b[0]))
 | |
| 		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
 | |
| 		if e == nil {
 | |
| 			return sid, UTF16ToString(db), accType, nil
 | |
| 		}
 | |
| 		if e != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return nil, "", 0, e
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return nil, "", 0, e
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // String converts SID to a string format suitable for display, storage, or transmission.
 | |
| func (sid *SID) String() string {
 | |
| 	var s *uint16
 | |
| 	e := ConvertSidToStringSid(sid, &s)
 | |
| 	if e != nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 	defer LocalFree((Handle)(unsafe.Pointer(s)))
 | |
| 	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:])
 | |
| }
 | |
| 
 | |
| // Len returns the length, in bytes, of a valid security identifier SID.
 | |
| func (sid *SID) Len() int {
 | |
| 	return int(GetLengthSid(sid))
 | |
| }
 | |
| 
 | |
| // Copy creates a duplicate of security identifier SID.
 | |
| func (sid *SID) Copy() (*SID, error) {
 | |
| 	b := make([]byte, sid.Len())
 | |
| 	sid2 := (*SID)(unsafe.Pointer(&b[0]))
 | |
| 	e := CopySid(uint32(len(b)), sid2, sid)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	return sid2, nil
 | |
| }
 | |
| 
 | |
| // IdentifierAuthority returns the identifier authority of the SID.
 | |
| func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
 | |
| 	return *getSidIdentifierAuthority(sid)
 | |
| }
 | |
| 
 | |
| // SubAuthorityCount returns the number of sub-authorities in the SID.
 | |
| func (sid *SID) SubAuthorityCount() uint8 {
 | |
| 	return *getSidSubAuthorityCount(sid)
 | |
| }
 | |
| 
 | |
| // SubAuthority returns the sub-authority of the SID as specified by
 | |
| // the index, which must be less than sid.SubAuthorityCount().
 | |
| func (sid *SID) SubAuthority(idx uint32) uint32 {
 | |
| 	if idx >= uint32(sid.SubAuthorityCount()) {
 | |
| 		panic("sub-authority index out of range")
 | |
| 	}
 | |
| 	return *getSidSubAuthority(sid, idx)
 | |
| }
 | |
| 
 | |
| // IsValid returns whether the SID has a valid revision and length.
 | |
| func (sid *SID) IsValid() bool {
 | |
| 	return isValidSid(sid)
 | |
| }
 | |
| 
 | |
| // Equals compares two SIDs for equality.
 | |
| func (sid *SID) Equals(sid2 *SID) bool {
 | |
| 	return EqualSid(sid, sid2)
 | |
| }
 | |
| 
 | |
| // IsWellKnown determines whether the SID matches the well-known sidType.
 | |
| func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
 | |
| 	return isWellKnownSid(sid, sidType)
 | |
| }
 | |
| 
 | |
| // LookupAccount retrieves the name of the account for this SID
 | |
| // and the name of the first domain on which this SID is found.
 | |
| // System specify target computer to search for.
 | |
| func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
 | |
| 	var sys *uint16
 | |
| 	if len(system) > 0 {
 | |
| 		sys, err = UTF16PtrFromString(system)
 | |
| 		if err != nil {
 | |
| 			return "", "", 0, err
 | |
| 		}
 | |
| 	}
 | |
| 	n := uint32(50)
 | |
| 	dn := uint32(50)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		db := make([]uint16, dn)
 | |
| 		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
 | |
| 		if e == nil {
 | |
| 			return UTF16ToString(b), UTF16ToString(db), accType, nil
 | |
| 		}
 | |
| 		if e != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return "", "", 0, e
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return "", "", 0, e
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Various types of pre-specified SIDs that can be synthesized and compared at runtime.
 | |
| type WELL_KNOWN_SID_TYPE uint32
 | |
| 
 | |
| const (
 | |
| 	WinNullSid                                    = 0
 | |
| 	WinWorldSid                                   = 1
 | |
| 	WinLocalSid                                   = 2
 | |
| 	WinCreatorOwnerSid                            = 3
 | |
| 	WinCreatorGroupSid                            = 4
 | |
| 	WinCreatorOwnerServerSid                      = 5
 | |
| 	WinCreatorGroupServerSid                      = 6
 | |
| 	WinNtAuthoritySid                             = 7
 | |
| 	WinDialupSid                                  = 8
 | |
| 	WinNetworkSid                                 = 9
 | |
| 	WinBatchSid                                   = 10
 | |
| 	WinInteractiveSid                             = 11
 | |
| 	WinServiceSid                                 = 12
 | |
| 	WinAnonymousSid                               = 13
 | |
| 	WinProxySid                                   = 14
 | |
| 	WinEnterpriseControllersSid                   = 15
 | |
| 	WinSelfSid                                    = 16
 | |
| 	WinAuthenticatedUserSid                       = 17
 | |
| 	WinRestrictedCodeSid                          = 18
 | |
| 	WinTerminalServerSid                          = 19
 | |
| 	WinRemoteLogonIdSid                           = 20
 | |
| 	WinLogonIdsSid                                = 21
 | |
| 	WinLocalSystemSid                             = 22
 | |
| 	WinLocalServiceSid                            = 23
 | |
| 	WinNetworkServiceSid                          = 24
 | |
| 	WinBuiltinDomainSid                           = 25
 | |
| 	WinBuiltinAdministratorsSid                   = 26
 | |
| 	WinBuiltinUsersSid                            = 27
 | |
| 	WinBuiltinGuestsSid                           = 28
 | |
| 	WinBuiltinPowerUsersSid                       = 29
 | |
| 	WinBuiltinAccountOperatorsSid                 = 30
 | |
| 	WinBuiltinSystemOperatorsSid                  = 31
 | |
| 	WinBuiltinPrintOperatorsSid                   = 32
 | |
| 	WinBuiltinBackupOperatorsSid                  = 33
 | |
| 	WinBuiltinReplicatorSid                       = 34
 | |
| 	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
 | |
| 	WinBuiltinRemoteDesktopUsersSid               = 36
 | |
| 	WinBuiltinNetworkConfigurationOperatorsSid    = 37
 | |
| 	WinAccountAdministratorSid                    = 38
 | |
| 	WinAccountGuestSid                            = 39
 | |
| 	WinAccountKrbtgtSid                           = 40
 | |
| 	WinAccountDomainAdminsSid                     = 41
 | |
| 	WinAccountDomainUsersSid                      = 42
 | |
| 	WinAccountDomainGuestsSid                     = 43
 | |
| 	WinAccountComputersSid                        = 44
 | |
| 	WinAccountControllersSid                      = 45
 | |
| 	WinAccountCertAdminsSid                       = 46
 | |
| 	WinAccountSchemaAdminsSid                     = 47
 | |
| 	WinAccountEnterpriseAdminsSid                 = 48
 | |
| 	WinAccountPolicyAdminsSid                     = 49
 | |
| 	WinAccountRasAndIasServersSid                 = 50
 | |
| 	WinNTLMAuthenticationSid                      = 51
 | |
| 	WinDigestAuthenticationSid                    = 52
 | |
| 	WinSChannelAuthenticationSid                  = 53
 | |
| 	WinThisOrganizationSid                        = 54
 | |
| 	WinOtherOrganizationSid                       = 55
 | |
| 	WinBuiltinIncomingForestTrustBuildersSid      = 56
 | |
| 	WinBuiltinPerfMonitoringUsersSid              = 57
 | |
| 	WinBuiltinPerfLoggingUsersSid                 = 58
 | |
| 	WinBuiltinAuthorizationAccessSid              = 59
 | |
| 	WinBuiltinTerminalServerLicenseServersSid     = 60
 | |
| 	WinBuiltinDCOMUsersSid                        = 61
 | |
| 	WinBuiltinIUsersSid                           = 62
 | |
| 	WinIUserSid                                   = 63
 | |
| 	WinBuiltinCryptoOperatorsSid                  = 64
 | |
| 	WinUntrustedLabelSid                          = 65
 | |
| 	WinLowLabelSid                                = 66
 | |
| 	WinMediumLabelSid                             = 67
 | |
| 	WinHighLabelSid                               = 68
 | |
| 	WinSystemLabelSid                             = 69
 | |
| 	WinWriteRestrictedCodeSid                     = 70
 | |
| 	WinCreatorOwnerRightsSid                      = 71
 | |
| 	WinCacheablePrincipalsGroupSid                = 72
 | |
| 	WinNonCacheablePrincipalsGroupSid             = 73
 | |
| 	WinEnterpriseReadonlyControllersSid           = 74
 | |
| 	WinAccountReadonlyControllersSid              = 75
 | |
| 	WinBuiltinEventLogReadersGroup                = 76
 | |
| 	WinNewEnterpriseReadonlyControllersSid        = 77
 | |
| 	WinBuiltinCertSvcDComAccessGroup              = 78
 | |
| 	WinMediumPlusLabelSid                         = 79
 | |
| 	WinLocalLogonSid                              = 80
 | |
| 	WinConsoleLogonSid                            = 81
 | |
| 	WinThisOrganizationCertificateSid             = 82
 | |
| 	WinApplicationPackageAuthoritySid             = 83
 | |
| 	WinBuiltinAnyPackageSid                       = 84
 | |
| 	WinCapabilityInternetClientSid                = 85
 | |
| 	WinCapabilityInternetClientServerSid          = 86
 | |
| 	WinCapabilityPrivateNetworkClientServerSid    = 87
 | |
| 	WinCapabilityPicturesLibrarySid               = 88
 | |
| 	WinCapabilityVideosLibrarySid                 = 89
 | |
| 	WinCapabilityMusicLibrarySid                  = 90
 | |
| 	WinCapabilityDocumentsLibrarySid              = 91
 | |
| 	WinCapabilitySharedUserCertificatesSid        = 92
 | |
| 	WinCapabilityEnterpriseAuthenticationSid      = 93
 | |
| 	WinCapabilityRemovableStorageSid              = 94
 | |
| 	WinBuiltinRDSRemoteAccessServersSid           = 95
 | |
| 	WinBuiltinRDSEndpointServersSid               = 96
 | |
| 	WinBuiltinRDSManagementServersSid             = 97
 | |
| 	WinUserModeDriversSid                         = 98
 | |
| 	WinBuiltinHyperVAdminsSid                     = 99
 | |
| 	WinAccountCloneableControllersSid             = 100
 | |
| 	WinBuiltinAccessControlAssistanceOperatorsSid = 101
 | |
| 	WinBuiltinRemoteManagementUsersSid            = 102
 | |
| 	WinAuthenticationAuthorityAssertedSid         = 103
 | |
| 	WinAuthenticationServiceAssertedSid           = 104
 | |
| 	WinLocalAccountSid                            = 105
 | |
| 	WinLocalAccountAndAdministratorSid            = 106
 | |
| 	WinAccountProtectedUsersSid                   = 107
 | |
| 	WinCapabilityAppointmentsSid                  = 108
 | |
| 	WinCapabilityContactsSid                      = 109
 | |
| 	WinAccountDefaultSystemManagedSid             = 110
 | |
| 	WinBuiltinDefaultSystemManagedGroupSid        = 111
 | |
| 	WinBuiltinStorageReplicaAdminsSid             = 112
 | |
| 	WinAccountKeyAdminsSid                        = 113
 | |
| 	WinAccountEnterpriseKeyAdminsSid              = 114
 | |
| 	WinAuthenticationKeyTrustSid                  = 115
 | |
| 	WinAuthenticationKeyPropertyMFASid            = 116
 | |
| 	WinAuthenticationKeyPropertyAttestationSid    = 117
 | |
| 	WinAuthenticationFreshKeyAuthSid              = 118
 | |
| 	WinBuiltinDeviceOwnersSid                     = 119
 | |
| )
 | |
| 
 | |
| // Creates a SID for a well-known predefined alias, generally using the constants of the form
 | |
| // Win*Sid, for the local machine.
 | |
| func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
 | |
| 	return CreateWellKnownDomainSid(sidType, nil)
 | |
| }
 | |
| 
 | |
| // Creates a SID for a well-known predefined alias, generally using the constants of the form
 | |
| // Win*Sid, for the domain specified by the domainSid parameter.
 | |
| func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
 | |
| 	n := uint32(50)
 | |
| 	for {
 | |
| 		b := make([]byte, n)
 | |
| 		sid := (*SID)(unsafe.Pointer(&b[0]))
 | |
| 		err := createWellKnownSid(sidType, domainSid, sid, &n)
 | |
| 		if err == nil {
 | |
| 			return sid, nil
 | |
| 		}
 | |
| 		if err != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	// do not reorder
 | |
| 	TOKEN_ASSIGN_PRIMARY = 1 << iota
 | |
| 	TOKEN_DUPLICATE
 | |
| 	TOKEN_IMPERSONATE
 | |
| 	TOKEN_QUERY
 | |
| 	TOKEN_QUERY_SOURCE
 | |
| 	TOKEN_ADJUST_PRIVILEGES
 | |
| 	TOKEN_ADJUST_GROUPS
 | |
| 	TOKEN_ADJUST_DEFAULT
 | |
| 	TOKEN_ADJUST_SESSIONID
 | |
| 
 | |
| 	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
 | |
| 		TOKEN_ASSIGN_PRIMARY |
 | |
| 		TOKEN_DUPLICATE |
 | |
| 		TOKEN_IMPERSONATE |
 | |
| 		TOKEN_QUERY |
 | |
| 		TOKEN_QUERY_SOURCE |
 | |
| 		TOKEN_ADJUST_PRIVILEGES |
 | |
| 		TOKEN_ADJUST_GROUPS |
 | |
| 		TOKEN_ADJUST_DEFAULT |
 | |
| 		TOKEN_ADJUST_SESSIONID
 | |
| 	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
 | |
| 	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
 | |
| 		TOKEN_ADJUST_PRIVILEGES |
 | |
| 		TOKEN_ADJUST_GROUPS |
 | |
| 		TOKEN_ADJUST_DEFAULT
 | |
| 	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	// do not reorder
 | |
| 	TokenUser = 1 + iota
 | |
| 	TokenGroups
 | |
| 	TokenPrivileges
 | |
| 	TokenOwner
 | |
| 	TokenPrimaryGroup
 | |
| 	TokenDefaultDacl
 | |
| 	TokenSource
 | |
| 	TokenType
 | |
| 	TokenImpersonationLevel
 | |
| 	TokenStatistics
 | |
| 	TokenRestrictedSids
 | |
| 	TokenSessionId
 | |
| 	TokenGroupsAndPrivileges
 | |
| 	TokenSessionReference
 | |
| 	TokenSandBoxInert
 | |
| 	TokenAuditPolicy
 | |
| 	TokenOrigin
 | |
| 	TokenElevationType
 | |
| 	TokenLinkedToken
 | |
| 	TokenElevation
 | |
| 	TokenHasRestrictions
 | |
| 	TokenAccessInformation
 | |
| 	TokenVirtualizationAllowed
 | |
| 	TokenVirtualizationEnabled
 | |
| 	TokenIntegrityLevel
 | |
| 	TokenUIAccess
 | |
| 	TokenMandatoryPolicy
 | |
| 	TokenLogonSid
 | |
| 	MaxTokenInfoClass
 | |
| )
 | |
| 
 | |
| // Group attributes inside of Tokengroups.Groups[i].Attributes
 | |
| const (
 | |
| 	SE_GROUP_MANDATORY          = 0x00000001
 | |
| 	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
 | |
| 	SE_GROUP_ENABLED            = 0x00000004
 | |
| 	SE_GROUP_OWNER              = 0x00000008
 | |
| 	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
 | |
| 	SE_GROUP_INTEGRITY          = 0x00000020
 | |
| 	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
 | |
| 	SE_GROUP_LOGON_ID           = 0xC0000000
 | |
| 	SE_GROUP_RESOURCE           = 0x20000000
 | |
| 	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
 | |
| )
 | |
| 
 | |
| // Privilege attributes
 | |
| const (
 | |
| 	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
 | |
| 	SE_PRIVILEGE_ENABLED            = 0x00000002
 | |
| 	SE_PRIVILEGE_REMOVED            = 0x00000004
 | |
| 	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
 | |
| 	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
 | |
| )
 | |
| 
 | |
| // Token types
 | |
| const (
 | |
| 	TokenPrimary       = 1
 | |
| 	TokenImpersonation = 2
 | |
| )
 | |
| 
 | |
| // Impersonation levels
 | |
| const (
 | |
| 	SecurityAnonymous      = 0
 | |
| 	SecurityIdentification = 1
 | |
| 	SecurityImpersonation  = 2
 | |
| 	SecurityDelegation     = 3
 | |
| )
 | |
| 
 | |
| type LUID struct {
 | |
| 	LowPart  uint32
 | |
| 	HighPart int32
 | |
| }
 | |
| 
 | |
| type LUIDAndAttributes struct {
 | |
| 	Luid       LUID
 | |
| 	Attributes uint32
 | |
| }
 | |
| 
 | |
| type SIDAndAttributes struct {
 | |
| 	Sid        *SID
 | |
| 	Attributes uint32
 | |
| }
 | |
| 
 | |
| type Tokenuser struct {
 | |
| 	User SIDAndAttributes
 | |
| }
 | |
| 
 | |
| type Tokenprimarygroup struct {
 | |
| 	PrimaryGroup *SID
 | |
| }
 | |
| 
 | |
| type Tokengroups struct {
 | |
| 	GroupCount uint32
 | |
| 	Groups     [1]SIDAndAttributes // Use AllGroups() for iterating.
 | |
| }
 | |
| 
 | |
| // AllGroups returns a slice that can be used to iterate over the groups in g.
 | |
| func (g *Tokengroups) AllGroups() []SIDAndAttributes {
 | |
| 	return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]
 | |
| }
 | |
| 
 | |
| type Tokenprivileges struct {
 | |
| 	PrivilegeCount uint32
 | |
| 	Privileges     [1]LUIDAndAttributes // Use AllPrivileges() for iterating.
 | |
| }
 | |
| 
 | |
| // AllPrivileges returns a slice that can be used to iterate over the privileges in p.
 | |
| func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {
 | |
| 	return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]
 | |
| }
 | |
| 
 | |
| type Tokenmandatorylabel struct {
 | |
| 	Label SIDAndAttributes
 | |
| }
 | |
| 
 | |
| func (tml *Tokenmandatorylabel) Size() uint32 {
 | |
| 	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
 | |
| }
 | |
| 
 | |
| // Authorization Functions
 | |
| //sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
 | |
| //sys	isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted
 | |
| //sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
 | |
| //sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
 | |
| //sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
 | |
| //sys	RevertToSelf() (err error) = advapi32.RevertToSelf
 | |
| //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
 | |
| //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
 | |
| //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
 | |
| //sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
 | |
| //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
 | |
| //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
 | |
| //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
 | |
| //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
 | |
| //sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
 | |
| //sys	getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW
 | |
| //sys	getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW
 | |
| 
 | |
| // An access token contains the security information for a logon session.
 | |
| // The system creates an access token when a user logs on, and every
 | |
| // process executed on behalf of the user has a copy of the token.
 | |
| // The token identifies the user, the user's groups, and the user's
 | |
| // privileges. The system uses the token to control access to securable
 | |
| // objects and to control the ability of the user to perform various
 | |
| // system-related operations on the local computer.
 | |
| type Token Handle
 | |
| 
 | |
| // OpenCurrentProcessToken opens an access token associated with current
 | |
| // process with TOKEN_QUERY access. It is a real token that needs to be closed.
 | |
| //
 | |
| // Deprecated: Explicitly call OpenProcessToken(CurrentProcess(), ...)
 | |
| // with the desired access instead, or use GetCurrentProcessToken for a
 | |
| // TOKEN_QUERY token.
 | |
| func OpenCurrentProcessToken() (Token, error) {
 | |
| 	var token Token
 | |
| 	err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token)
 | |
| 	return token, err
 | |
| }
 | |
| 
 | |
| // GetCurrentProcessToken returns the access token associated with
 | |
| // the current process. It is a pseudo token that does not need
 | |
| // to be closed.
 | |
| func GetCurrentProcessToken() Token {
 | |
| 	return Token(^uintptr(4 - 1))
 | |
| }
 | |
| 
 | |
| // GetCurrentThreadToken return the access token associated with
 | |
| // the current thread. It is a pseudo token that does not need
 | |
| // to be closed.
 | |
| func GetCurrentThreadToken() Token {
 | |
| 	return Token(^uintptr(5 - 1))
 | |
| }
 | |
| 
 | |
| // GetCurrentThreadEffectiveToken returns the effective access token
 | |
| // associated with the current thread. It is a pseudo token that does
 | |
| // not need to be closed.
 | |
| func GetCurrentThreadEffectiveToken() Token {
 | |
| 	return Token(^uintptr(6 - 1))
 | |
| }
 | |
| 
 | |
| // Close releases access to access token.
 | |
| func (t Token) Close() error {
 | |
| 	return CloseHandle(Handle(t))
 | |
| }
 | |
| 
 | |
| // getInfo retrieves a specified type of information about an access token.
 | |
| func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
 | |
| 	n := uint32(initSize)
 | |
| 	for {
 | |
| 		b := make([]byte, n)
 | |
| 		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
 | |
| 		if e == nil {
 | |
| 			return unsafe.Pointer(&b[0]), nil
 | |
| 		}
 | |
| 		if e != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return nil, e
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return nil, e
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetTokenUser retrieves access token t user account information.
 | |
| func (t Token) GetTokenUser() (*Tokenuser, error) {
 | |
| 	i, e := t.getInfo(TokenUser, 50)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	return (*Tokenuser)(i), nil
 | |
| }
 | |
| 
 | |
| // GetTokenGroups retrieves group accounts associated with access token t.
 | |
| func (t Token) GetTokenGroups() (*Tokengroups, error) {
 | |
| 	i, e := t.getInfo(TokenGroups, 50)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	return (*Tokengroups)(i), nil
 | |
| }
 | |
| 
 | |
| // GetTokenPrimaryGroup retrieves access token t primary group information.
 | |
| // A pointer to a SID structure representing a group that will become
 | |
| // the primary group of any objects created by a process using this access token.
 | |
| func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
 | |
| 	i, e := t.getInfo(TokenPrimaryGroup, 50)
 | |
| 	if e != nil {
 | |
| 		return nil, e
 | |
| 	}
 | |
| 	return (*Tokenprimarygroup)(i), nil
 | |
| }
 | |
| 
 | |
| // GetUserProfileDirectory retrieves path to the
 | |
| // root directory of the access token t user's profile.
 | |
| func (t Token) GetUserProfileDirectory() (string, error) {
 | |
| 	n := uint32(100)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		e := GetUserProfileDirectory(t, &b[0], &n)
 | |
| 		if e == nil {
 | |
| 			return UTF16ToString(b), nil
 | |
| 		}
 | |
| 		if e != ERROR_INSUFFICIENT_BUFFER {
 | |
| 			return "", e
 | |
| 		}
 | |
| 		if n <= uint32(len(b)) {
 | |
| 			return "", e
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // IsElevated returns whether the current token is elevated from a UAC perspective.
 | |
| func (token Token) IsElevated() bool {
 | |
| 	var isElevated uint32
 | |
| 	var outLen uint32
 | |
| 	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
 | |
| 	if err != nil {
 | |
| 		return false
 | |
| 	}
 | |
| 	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
 | |
| }
 | |
| 
 | |
| // GetLinkedToken returns the linked token, which may be an elevated UAC token.
 | |
| func (token Token) GetLinkedToken() (Token, error) {
 | |
| 	var linkedToken Token
 | |
| 	var outLen uint32
 | |
| 	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
 | |
| 	if err != nil {
 | |
| 		return Token(0), err
 | |
| 	}
 | |
| 	return linkedToken, nil
 | |
| }
 | |
| 
 | |
| // GetSystemDirectory retrieves the path to current location of the system
 | |
| // directory, which is typically, though not always, `C:\Windows\System32`.
 | |
| func GetSystemDirectory() (string, error) {
 | |
| 	n := uint32(MAX_PATH)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		l, e := getSystemDirectory(&b[0], n)
 | |
| 		if e != nil {
 | |
| 			return "", e
 | |
| 		}
 | |
| 		if l <= n {
 | |
| 			return UTF16ToString(b[:l]), nil
 | |
| 		}
 | |
| 		n = l
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetWindowsDirectory retrieves the path to current location of the Windows
 | |
| // directory, which is typically, though not always, `C:\Windows`. This may
 | |
| // be a private user directory in the case that the application is running
 | |
| // under a terminal server.
 | |
| func GetWindowsDirectory() (string, error) {
 | |
| 	n := uint32(MAX_PATH)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		l, e := getWindowsDirectory(&b[0], n)
 | |
| 		if e != nil {
 | |
| 			return "", e
 | |
| 		}
 | |
| 		if l <= n {
 | |
| 			return UTF16ToString(b[:l]), nil
 | |
| 		}
 | |
| 		n = l
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetSystemWindowsDirectory retrieves the path to current location of the
 | |
| // Windows directory, which is typically, though not always, `C:\Windows`.
 | |
| func GetSystemWindowsDirectory() (string, error) {
 | |
| 	n := uint32(MAX_PATH)
 | |
| 	for {
 | |
| 		b := make([]uint16, n)
 | |
| 		l, e := getSystemWindowsDirectory(&b[0], n)
 | |
| 		if e != nil {
 | |
| 			return "", e
 | |
| 		}
 | |
| 		if l <= n {
 | |
| 			return UTF16ToString(b[:l]), nil
 | |
| 		}
 | |
| 		n = l
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // IsMember reports whether the access token t is a member of the provided SID.
 | |
| func (t Token) IsMember(sid *SID) (bool, error) {
 | |
| 	var b int32
 | |
| 	if e := checkTokenMembership(t, sid, &b); e != nil {
 | |
| 		return false, e
 | |
| 	}
 | |
| 	return b != 0, nil
 | |
| }
 | |
| 
 | |
| // IsRestricted reports whether the access token t is a restricted token.
 | |
| func (t Token) IsRestricted() (isRestricted bool, err error) {
 | |
| 	isRestricted, err = isTokenRestricted(t)
 | |
| 	if !isRestricted && err == syscall.EINVAL {
 | |
| 		// If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token.
 | |
| 		err = nil
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	WTS_CONSOLE_CONNECT        = 0x1
 | |
| 	WTS_CONSOLE_DISCONNECT     = 0x2
 | |
| 	WTS_REMOTE_CONNECT         = 0x3
 | |
| 	WTS_REMOTE_DISCONNECT      = 0x4
 | |
| 	WTS_SESSION_LOGON          = 0x5
 | |
| 	WTS_SESSION_LOGOFF         = 0x6
 | |
| 	WTS_SESSION_LOCK           = 0x7
 | |
| 	WTS_SESSION_UNLOCK         = 0x8
 | |
| 	WTS_SESSION_REMOTE_CONTROL = 0x9
 | |
| 	WTS_SESSION_CREATE         = 0xa
 | |
| 	WTS_SESSION_TERMINATE      = 0xb
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	WTSActive       = 0
 | |
| 	WTSConnected    = 1
 | |
| 	WTSConnectQuery = 2
 | |
| 	WTSShadow       = 3
 | |
| 	WTSDisconnected = 4
 | |
| 	WTSIdle         = 5
 | |
| 	WTSListen       = 6
 | |
| 	WTSReset        = 7
 | |
| 	WTSDown         = 8
 | |
| 	WTSInit         = 9
 | |
| )
 | |
| 
 | |
| type WTSSESSION_NOTIFICATION struct {
 | |
| 	Size      uint32
 | |
| 	SessionID uint32
 | |
| }
 | |
| 
 | |
| type WTS_SESSION_INFO struct {
 | |
| 	SessionID         uint32
 | |
| 	WindowStationName *uint16
 | |
| 	State             uint32
 | |
| }
 | |
| 
 | |
| //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
 | |
| //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
 | |
| //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
 | |
| //sys WTSGetActiveConsoleSessionId() (sessionID uint32)
 | |
| 
 | |
| type ACL struct {
 | |
| 	aclRevision byte
 | |
| 	sbz1        byte
 | |
| 	aclSize     uint16
 | |
| 	aceCount    uint16
 | |
| 	sbz2        uint16
 | |
| }
 | |
| 
 | |
| type SECURITY_DESCRIPTOR struct {
 | |
| 	revision byte
 | |
| 	sbz1     byte
 | |
| 	control  SECURITY_DESCRIPTOR_CONTROL
 | |
| 	owner    *SID
 | |
| 	group    *SID
 | |
| 	sacl     *ACL
 | |
| 	dacl     *ACL
 | |
| }
 | |
| 
 | |
| type SECURITY_QUALITY_OF_SERVICE struct {
 | |
| 	Length              uint32
 | |
| 	ImpersonationLevel  uint32
 | |
| 	ContextTrackingMode byte
 | |
| 	EffectiveOnly       byte
 | |
| }
 | |
| 
 | |
| // Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
 | |
| const (
 | |
| 	SECURITY_STATIC_TRACKING  = 0
 | |
| 	SECURITY_DYNAMIC_TRACKING = 1
 | |
| )
 | |
| 
 | |
| type SecurityAttributes struct {
 | |
| 	Length             uint32
 | |
| 	SecurityDescriptor *SECURITY_DESCRIPTOR
 | |
| 	InheritHandle      uint32
 | |
| }
 | |
| 
 | |
| type SE_OBJECT_TYPE uint32
 | |
| 
 | |
| // Constants for type SE_OBJECT_TYPE
 | |
| const (
 | |
| 	SE_UNKNOWN_OBJECT_TYPE     = 0
 | |
| 	SE_FILE_OBJECT             = 1
 | |
| 	SE_SERVICE                 = 2
 | |
| 	SE_PRINTER                 = 3
 | |
| 	SE_REGISTRY_KEY            = 4
 | |
| 	SE_LMSHARE                 = 5
 | |
| 	SE_KERNEL_OBJECT           = 6
 | |
| 	SE_WINDOW_OBJECT           = 7
 | |
| 	SE_DS_OBJECT               = 8
 | |
| 	SE_DS_OBJECT_ALL           = 9
 | |
| 	SE_PROVIDER_DEFINED_OBJECT = 10
 | |
| 	SE_WMIGUID_OBJECT          = 11
 | |
| 	SE_REGISTRY_WOW64_32KEY    = 12
 | |
| 	SE_REGISTRY_WOW64_64KEY    = 13
 | |
| )
 | |
| 
 | |
| type SECURITY_INFORMATION uint32
 | |
| 
 | |
| // Constants for type SECURITY_INFORMATION
 | |
| const (
 | |
| 	OWNER_SECURITY_INFORMATION            = 0x00000001
 | |
| 	GROUP_SECURITY_INFORMATION            = 0x00000002
 | |
| 	DACL_SECURITY_INFORMATION             = 0x00000004
 | |
| 	SACL_SECURITY_INFORMATION             = 0x00000008
 | |
| 	LABEL_SECURITY_INFORMATION            = 0x00000010
 | |
| 	ATTRIBUTE_SECURITY_INFORMATION        = 0x00000020
 | |
| 	SCOPE_SECURITY_INFORMATION            = 0x00000040
 | |
| 	BACKUP_SECURITY_INFORMATION           = 0x00010000
 | |
| 	PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000
 | |
| 	PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000
 | |
| 	UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
 | |
| 	UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
 | |
| )
 | |
| 
 | |
| type SECURITY_DESCRIPTOR_CONTROL uint16
 | |
| 
 | |
| // Constants for type SECURITY_DESCRIPTOR_CONTROL
 | |
| const (
 | |
| 	SE_OWNER_DEFAULTED       = 0x0001
 | |
| 	SE_GROUP_DEFAULTED       = 0x0002
 | |
| 	SE_DACL_PRESENT          = 0x0004
 | |
| 	SE_DACL_DEFAULTED        = 0x0008
 | |
| 	SE_SACL_PRESENT          = 0x0010
 | |
| 	SE_SACL_DEFAULTED        = 0x0020
 | |
| 	SE_DACL_AUTO_INHERIT_REQ = 0x0100
 | |
| 	SE_SACL_AUTO_INHERIT_REQ = 0x0200
 | |
| 	SE_DACL_AUTO_INHERITED   = 0x0400
 | |
| 	SE_SACL_AUTO_INHERITED   = 0x0800
 | |
| 	SE_DACL_PROTECTED        = 0x1000
 | |
| 	SE_SACL_PROTECTED        = 0x2000
 | |
| 	SE_RM_CONTROL_VALID      = 0x4000
 | |
| 	SE_SELF_RELATIVE         = 0x8000
 | |
| )
 | |
| 
 | |
| type ACCESS_MASK uint32
 | |
| 
 | |
| // Constants for type ACCESS_MASK
 | |
| const (
 | |
| 	DELETE                   = 0x00010000
 | |
| 	READ_CONTROL             = 0x00020000
 | |
| 	WRITE_DAC                = 0x00040000
 | |
| 	WRITE_OWNER              = 0x00080000
 | |
| 	SYNCHRONIZE              = 0x00100000
 | |
| 	STANDARD_RIGHTS_REQUIRED = 0x000F0000
 | |
| 	STANDARD_RIGHTS_READ     = READ_CONTROL
 | |
| 	STANDARD_RIGHTS_WRITE    = READ_CONTROL
 | |
| 	STANDARD_RIGHTS_EXECUTE  = READ_CONTROL
 | |
| 	STANDARD_RIGHTS_ALL      = 0x001F0000
 | |
| 	SPECIFIC_RIGHTS_ALL      = 0x0000FFFF
 | |
| 	ACCESS_SYSTEM_SECURITY   = 0x01000000
 | |
| 	MAXIMUM_ALLOWED          = 0x02000000
 | |
| 	GENERIC_READ             = 0x80000000
 | |
| 	GENERIC_WRITE            = 0x40000000
 | |
| 	GENERIC_EXECUTE          = 0x20000000
 | |
| 	GENERIC_ALL              = 0x10000000
 | |
| )
 | |
| 
 | |
| type ACCESS_MODE uint32
 | |
| 
 | |
| // Constants for type ACCESS_MODE
 | |
| const (
 | |
| 	NOT_USED_ACCESS   = 0
 | |
| 	GRANT_ACCESS      = 1
 | |
| 	SET_ACCESS        = 2
 | |
| 	DENY_ACCESS       = 3
 | |
| 	REVOKE_ACCESS     = 4
 | |
| 	SET_AUDIT_SUCCESS = 5
 | |
| 	SET_AUDIT_FAILURE = 6
 | |
| )
 | |
| 
 | |
| // Constants for AceFlags and Inheritance fields
 | |
| const (
 | |
| 	NO_INHERITANCE                     = 0x0
 | |
| 	SUB_OBJECTS_ONLY_INHERIT           = 0x1
 | |
| 	SUB_CONTAINERS_ONLY_INHERIT        = 0x2
 | |
| 	SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3
 | |
| 	INHERIT_NO_PROPAGATE               = 0x4
 | |
| 	INHERIT_ONLY                       = 0x8
 | |
| 	INHERITED_ACCESS_ENTRY             = 0x10
 | |
| 	INHERITED_PARENT                   = 0x10000000
 | |
| 	INHERITED_GRANDPARENT              = 0x20000000
 | |
| 	OBJECT_INHERIT_ACE                 = 0x1
 | |
| 	CONTAINER_INHERIT_ACE              = 0x2
 | |
| 	NO_PROPAGATE_INHERIT_ACE           = 0x4
 | |
| 	INHERIT_ONLY_ACE                   = 0x8
 | |
| 	INHERITED_ACE                      = 0x10
 | |
| 	VALID_INHERIT_FLAGS                = 0x1F
 | |
| )
 | |
| 
 | |
| type MULTIPLE_TRUSTEE_OPERATION uint32
 | |
| 
 | |
| // Constants for MULTIPLE_TRUSTEE_OPERATION
 | |
| const (
 | |
| 	NO_MULTIPLE_TRUSTEE    = 0
 | |
| 	TRUSTEE_IS_IMPERSONATE = 1
 | |
| )
 | |
| 
 | |
| type TRUSTEE_FORM uint32
 | |
| 
 | |
| // Constants for TRUSTEE_FORM
 | |
| const (
 | |
| 	TRUSTEE_IS_SID              = 0
 | |
| 	TRUSTEE_IS_NAME             = 1
 | |
| 	TRUSTEE_BAD_FORM            = 2
 | |
| 	TRUSTEE_IS_OBJECTS_AND_SID  = 3
 | |
| 	TRUSTEE_IS_OBJECTS_AND_NAME = 4
 | |
| )
 | |
| 
 | |
| type TRUSTEE_TYPE uint32
 | |
| 
 | |
| // Constants for TRUSTEE_TYPE
 | |
| const (
 | |
| 	TRUSTEE_IS_UNKNOWN          = 0
 | |
| 	TRUSTEE_IS_USER             = 1
 | |
| 	TRUSTEE_IS_GROUP            = 2
 | |
| 	TRUSTEE_IS_DOMAIN           = 3
 | |
| 	TRUSTEE_IS_ALIAS            = 4
 | |
| 	TRUSTEE_IS_WELL_KNOWN_GROUP = 5
 | |
| 	TRUSTEE_IS_DELETED          = 6
 | |
| 	TRUSTEE_IS_INVALID          = 7
 | |
| 	TRUSTEE_IS_COMPUTER         = 8
 | |
| )
 | |
| 
 | |
| // Constants for ObjectsPresent field
 | |
| const (
 | |
| 	ACE_OBJECT_TYPE_PRESENT           = 0x1
 | |
| 	ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
 | |
| )
 | |
| 
 | |
| type EXPLICIT_ACCESS struct {
 | |
| 	AccessPermissions ACCESS_MASK
 | |
| 	AccessMode        ACCESS_MODE
 | |
| 	Inheritance       uint32
 | |
| 	Trustee           TRUSTEE
 | |
| }
 | |
| 
 | |
| // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
 | |
| type TrusteeValue uintptr
 | |
| 
 | |
| func TrusteeValueFromString(str string) TrusteeValue {
 | |
| 	return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
 | |
| }
 | |
| func TrusteeValueFromSID(sid *SID) TrusteeValue {
 | |
| 	return TrusteeValue(unsafe.Pointer(sid))
 | |
| }
 | |
| func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
 | |
| 	return TrusteeValue(unsafe.Pointer(objectsAndSid))
 | |
| }
 | |
| func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
 | |
| 	return TrusteeValue(unsafe.Pointer(objectsAndName))
 | |
| }
 | |
| 
 | |
| type TRUSTEE struct {
 | |
| 	MultipleTrustee          *TRUSTEE
 | |
| 	MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
 | |
| 	TrusteeForm              TRUSTEE_FORM
 | |
| 	TrusteeType              TRUSTEE_TYPE
 | |
| 	TrusteeValue             TrusteeValue
 | |
| }
 | |
| 
 | |
| type OBJECTS_AND_SID struct {
 | |
| 	ObjectsPresent          uint32
 | |
| 	ObjectTypeGuid          GUID
 | |
| 	InheritedObjectTypeGuid GUID
 | |
| 	Sid                     *SID
 | |
| }
 | |
| 
 | |
| type OBJECTS_AND_NAME struct {
 | |
| 	ObjectsPresent          uint32
 | |
| 	ObjectType              SE_OBJECT_TYPE
 | |
| 	ObjectTypeName          *uint16
 | |
| 	InheritedObjectTypeName *uint16
 | |
| 	Name                    *uint16
 | |
| }
 | |
| 
 | |
| //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
 | |
| //sys	SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo
 | |
| //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
 | |
| //sys	SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
 | |
| //sys	SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity
 | |
| 
 | |
| //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
 | |
| //sys	initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
 | |
| 
 | |
| //sys	getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl
 | |
| //sys	getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl
 | |
| //sys	getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl
 | |
| //sys	getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner
 | |
| //sys	getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup
 | |
| //sys	getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength
 | |
| //sys	getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl
 | |
| //sys	isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor
 | |
| 
 | |
| //sys	setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl
 | |
| //sys	setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
 | |
| //sys	setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
 | |
| //sys	setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner
 | |
| //sys	setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup
 | |
| //sys	setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl
 | |
| 
 | |
| //sys	convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
 | |
| //sys	convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
 | |
| 
 | |
| //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
 | |
| //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
 | |
| 
 | |
| //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
 | |
| 
 | |
| // Control returns the security descriptor control bits.
 | |
| func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
 | |
| 	err = getSecurityDescriptorControl(sd, &control, &revision)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetControl sets the security descriptor control bits.
 | |
| func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {
 | |
| 	return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)
 | |
| }
 | |
| 
 | |
| // RMControl returns the security descriptor resource manager control bits.
 | |
| func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {
 | |
| 	err = getSecurityDescriptorRMControl(sd, &control)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetRMControl sets the security descriptor resource manager control bits.
 | |
| func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {
 | |
| 	setSecurityDescriptorRMControl(sd, &rmControl)
 | |
| }
 | |
| 
 | |
| // DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil
 | |
| // if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns
 | |
| // ERROR_OBJECT_NOT_FOUND.
 | |
| func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {
 | |
| 	var present bool
 | |
| 	err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)
 | |
| 	if !present {
 | |
| 		err = ERROR_OBJECT_NOT_FOUND
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetDACL sets the absolute security descriptor DACL.
 | |
| func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {
 | |
| 	return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted)
 | |
| }
 | |
| 
 | |
| // SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil
 | |
| // if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns
 | |
| // ERROR_OBJECT_NOT_FOUND.
 | |
| func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {
 | |
| 	var present bool
 | |
| 	err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)
 | |
| 	if !present {
 | |
| 		err = ERROR_OBJECT_NOT_FOUND
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetSACL sets the absolute security descriptor SACL.
 | |
| func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {
 | |
| 	return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)
 | |
| }
 | |
| 
 | |
| // Owner returns the security descriptor owner and whether it was defaulted.
 | |
| func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {
 | |
| 	err = getSecurityDescriptorOwner(sd, &owner, &defaulted)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetOwner sets the absolute security descriptor owner.
 | |
| func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {
 | |
| 	return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)
 | |
| }
 | |
| 
 | |
| // Group returns the security descriptor group and whether it was defaulted.
 | |
| func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {
 | |
| 	err = getSecurityDescriptorGroup(sd, &group, &defaulted)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // SetGroup sets the absolute security descriptor owner.
 | |
| func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {
 | |
| 	return setSecurityDescriptorGroup(absoluteSD, group, defaulted)
 | |
| }
 | |
| 
 | |
| // Length returns the length of the security descriptor.
 | |
| func (sd *SECURITY_DESCRIPTOR) Length() uint32 {
 | |
| 	return getSecurityDescriptorLength(sd)
 | |
| }
 | |
| 
 | |
| // IsValid returns whether the security descriptor is valid.
 | |
| func (sd *SECURITY_DESCRIPTOR) IsValid() bool {
 | |
| 	return isValidSecurityDescriptor(sd)
 | |
| }
 | |
| 
 | |
| // String returns the SDDL form of the security descriptor, with a function signature that can be
 | |
| // used with %v formatting directives.
 | |
| func (sd *SECURITY_DESCRIPTOR) String() string {
 | |
| 	var sddl *uint16
 | |
| 	err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)
 | |
| 	if err != nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(sddl)))
 | |
| 	return UTF16PtrToString(sddl)
 | |
| }
 | |
| 
 | |
| // ToAbsolute converts a self-relative security descriptor into an absolute one.
 | |
| func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
 | |
| 	control, _, err := selfRelativeSD.Control()
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	if control&SE_SELF_RELATIVE == 0 {
 | |
| 		err = ERROR_INVALID_PARAMETER
 | |
| 		return
 | |
| 	}
 | |
| 	var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32
 | |
| 	err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,
 | |
| 		nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)
 | |
| 	switch err {
 | |
| 	case ERROR_INSUFFICIENT_BUFFER:
 | |
| 	case nil:
 | |
| 		// makeAbsoluteSD is expected to fail, but it succeeds.
 | |
| 		return nil, ERROR_INTERNAL_ERROR
 | |
| 	default:
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	if absoluteSDSize > 0 {
 | |
| 		absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
 | |
| 	}
 | |
| 	var (
 | |
| 		dacl  *ACL
 | |
| 		sacl  *ACL
 | |
| 		owner *SID
 | |
| 		group *SID
 | |
| 	)
 | |
| 	if daclSize > 0 {
 | |
| 		dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
 | |
| 	}
 | |
| 	if saclSize > 0 {
 | |
| 		sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
 | |
| 	}
 | |
| 	if ownerSize > 0 {
 | |
| 		owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
 | |
| 	}
 | |
| 	if groupSize > 0 {
 | |
| 		group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
 | |
| 	}
 | |
| 	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
 | |
| 		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // ToSelfRelative converts an absolute security descriptor into a self-relative one.
 | |
| func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
 | |
| 	control, _, err := absoluteSD.Control()
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	if control&SE_SELF_RELATIVE != 0 {
 | |
| 		err = ERROR_INVALID_PARAMETER
 | |
| 		return
 | |
| 	}
 | |
| 	var selfRelativeSDSize uint32
 | |
| 	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
 | |
| 	switch err {
 | |
| 	case ERROR_INSUFFICIENT_BUFFER:
 | |
| 	case nil:
 | |
| 		// makeSelfRelativeSD is expected to fail, but it succeeds.
 | |
| 		return nil, ERROR_INTERNAL_ERROR
 | |
| 	default:
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	if selfRelativeSDSize > 0 {
 | |
| 		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
 | |
| 	}
 | |
| 	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
 | |
| 	sdLen := int(selfRelativeSD.Length())
 | |
| 	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
 | |
| 	if sdLen < min {
 | |
| 		sdLen = min
 | |
| 	}
 | |
| 
 | |
| 	var src []byte
 | |
| 	h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
 | |
| 	h.Data = unsafe.Pointer(selfRelativeSD)
 | |
| 	h.Len = sdLen
 | |
| 	h.Cap = sdLen
 | |
| 
 | |
| 	const psize = int(unsafe.Sizeof(uintptr(0)))
 | |
| 
 | |
| 	var dst []byte
 | |
| 	h = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
 | |
| 	alloc := make([]uintptr, (sdLen+psize-1)/psize)
 | |
| 	h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data
 | |
| 	h.Len = sdLen
 | |
| 	h.Cap = sdLen
 | |
| 
 | |
| 	copy(dst, src)
 | |
| 	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
 | |
| }
 | |
| 
 | |
| // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
 | |
| // self-relative security descriptor object allocated on the Go heap.
 | |
| func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
 | |
| 	var winHeapSD *SECURITY_DESCRIPTOR
 | |
| 	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
 | |
| 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
 | |
| }
 | |
| 
 | |
| // GetSecurityInfo queries the security information for a given handle and returns the self-relative security
 | |
| // descriptor result on the Go heap.
 | |
| func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
 | |
| 	var winHeapSD *SECURITY_DESCRIPTOR
 | |
| 	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
 | |
| 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
 | |
| }
 | |
| 
 | |
| // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
 | |
| // descriptor result on the Go heap.
 | |
| func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
 | |
| 	var winHeapSD *SECURITY_DESCRIPTOR
 | |
| 	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
 | |
| 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
 | |
| }
 | |
| 
 | |
| // BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
 | |
| // prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
 | |
| // result on the Go heap.
 | |
| func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
 | |
| 	var winHeapSD *SECURITY_DESCRIPTOR
 | |
| 	var winHeapSDSize uint32
 | |
| 	var firstAccessEntry *EXPLICIT_ACCESS
 | |
| 	if len(accessEntries) > 0 {
 | |
| 		firstAccessEntry = &accessEntries[0]
 | |
| 	}
 | |
| 	var firstAuditEntry *EXPLICIT_ACCESS
 | |
| 	if len(auditEntries) > 0 {
 | |
| 		firstAuditEntry = &auditEntries[0]
 | |
| 	}
 | |
| 	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
 | |
| 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
 | |
| }
 | |
| 
 | |
| // NewSecurityDescriptor creates and initializes a new absolute security descriptor.
 | |
| func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
 | |
| 	absoluteSD = &SECURITY_DESCRIPTOR{}
 | |
| 	err = initializeSecurityDescriptor(absoluteSD, 1)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
 | |
| // Both explicitEntries and mergedACL are optional and can be nil.
 | |
| func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
 | |
| 	var firstExplicitEntry *EXPLICIT_ACCESS
 | |
| 	if len(explicitEntries) > 0 {
 | |
| 		firstExplicitEntry = &explicitEntries[0]
 | |
| 	}
 | |
| 	var winHeapACL *ACL
 | |
| 	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
 | |
| 	aclBytes := make([]byte, winHeapACL.aclSize)
 | |
| 	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
 | |
| 	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
 | |
| }
 |