go-tg-screenshot-bot
1458 строк · 53.1 Кб
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
5package windows6
7import (8"syscall"9"unsafe"10)
11
12const (13NameUnknown = 014NameFullyQualifiedDN = 115NameSamCompatible = 216NameDisplay = 317NameUniqueId = 618NameCanonical = 719NameUserPrincipal = 820NameCanonicalEx = 921NameServicePrincipal = 1022NameDnsDomain = 1223)
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.
32func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {33u, e := UTF16PtrFromString(username)34if e != nil {35return "", e36}37n := uint32(50)38for {39b := make([]uint16, n)40e = TranslateName(u, from, to, &b[0], &n)41if e == nil {42return UTF16ToString(b[:n]), nil43}44if e != ERROR_INSUFFICIENT_BUFFER {45return "", e46}47if n <= uint32(len(b)) {48return "", e49}50}51}
52
53const (54// do not reorder55NetSetupUnknownStatus = iota56NetSetupUnjoined
57NetSetupWorkgroupName
58NetSetupDomainName
59)
60
61type UserInfo10 struct {62Name *uint1663Comment *uint1664UsrComment *uint1665FullName *uint1666}
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
73const (74// do not reorder75SidTypeUser = 1 + iota76SidTypeGroup
77SidTypeDomain
78SidTypeAlias
79SidTypeWellKnownGroup
80SidTypeDeletedAccount
81SidTypeInvalid
82SidTypeUnknown
83SidTypeComputer
84SidTypeLabel
85)
86
87type SidIdentifierAuthority struct {88Value [6]byte89}
90
91var (92SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}93SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}94SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}95SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}96SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}97SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}98SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}99)
100
101const (102SECURITY_NULL_RID = 0103SECURITY_WORLD_RID = 0104SECURITY_LOCAL_RID = 0105SECURITY_CREATOR_OWNER_RID = 0106SECURITY_CREATOR_GROUP_RID = 1107SECURITY_DIALUP_RID = 1108SECURITY_NETWORK_RID = 2109SECURITY_BATCH_RID = 3110SECURITY_INTERACTIVE_RID = 4111SECURITY_LOGON_IDS_RID = 5112SECURITY_SERVICE_RID = 6113SECURITY_LOCAL_SYSTEM_RID = 18114SECURITY_BUILTIN_DOMAIN_RID = 32115SECURITY_PRINCIPAL_SELF_RID = 10116SECURITY_CREATOR_OWNER_SERVER_RID = 0x2117SECURITY_CREATOR_GROUP_SERVER_RID = 0x3118SECURITY_LOGON_IDS_RID_COUNT = 0x3119SECURITY_ANONYMOUS_LOGON_RID = 0x7120SECURITY_PROXY_RID = 0x8121SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9122SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID123SECURITY_AUTHENTICATED_USER_RID = 0xb124SECURITY_RESTRICTED_CODE_RID = 0xc125SECURITY_NT_NON_UNIQUE_RID = 0x15126)
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
130const (131DOMAIN_ALIAS_RID_ADMINS = 0x220132DOMAIN_ALIAS_RID_USERS = 0x221133DOMAIN_ALIAS_RID_GUESTS = 0x222134DOMAIN_ALIAS_RID_POWER_USERS = 0x223135DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224136DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225137DOMAIN_ALIAS_RID_PRINT_OPS = 0x226138DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227139DOMAIN_ALIAS_RID_REPLICATOR = 0x228140DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229141DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a142DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b143DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c144DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d145DOMAIN_ALIAS_RID_MONITORING_USERS = 0x22e146DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f147DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230148DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231149DOMAIN_ALIAS_RID_DCOM_USERS = 0x232150DOMAIN_ALIAS_RID_IUSERS = 0x238151DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239152DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b153DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c154DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d155DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e156)
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.
176type SID struct{}177
178// StringToSid converts a string-format security identifier
179// SID into a valid, functional SID.
180func StringToSid(s string) (*SID, error) {181var sid *SID182p, e := UTF16PtrFromString(s)183if e != nil {184return nil, e185}186e = ConvertStringSidToSid(p, &sid)187if e != nil {188return nil, e189}190defer LocalFree((Handle)(unsafe.Pointer(sid)))191return 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.
197func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {198if len(account) == 0 {199return nil, "", 0, syscall.EINVAL200}201acc, e := UTF16PtrFromString(account)202if e != nil {203return nil, "", 0, e204}205var sys *uint16206if len(system) > 0 {207sys, e = UTF16PtrFromString(system)208if e != nil {209return nil, "", 0, e210}211}212n := uint32(50)213dn := uint32(50)214for {215b := make([]byte, n)216db := make([]uint16, dn)217sid = (*SID)(unsafe.Pointer(&b[0]))218e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)219if e == nil {220return sid, UTF16ToString(db), accType, nil221}222if e != ERROR_INSUFFICIENT_BUFFER {223return nil, "", 0, e224}225if n <= uint32(len(b)) {226return nil, "", 0, e227}228}229}
230
231// String converts SID to a string format suitable for display, storage, or transmission.
232func (sid *SID) String() string {233var s *uint16234e := ConvertSidToStringSid(sid, &s)235if e != nil {236return ""237}238defer LocalFree((Handle)(unsafe.Pointer(s)))239return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:])240}
241
242// Len returns the length, in bytes, of a valid security identifier SID.
243func (sid *SID) Len() int {244return int(GetLengthSid(sid))245}
246
247// Copy creates a duplicate of security identifier SID.
248func (sid *SID) Copy() (*SID, error) {249b := make([]byte, sid.Len())250sid2 := (*SID)(unsafe.Pointer(&b[0]))251e := CopySid(uint32(len(b)), sid2, sid)252if e != nil {253return nil, e254}255return sid2, nil256}
257
258// IdentifierAuthority returns the identifier authority of the SID.
259func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {260return *getSidIdentifierAuthority(sid)261}
262
263// SubAuthorityCount returns the number of sub-authorities in the SID.
264func (sid *SID) SubAuthorityCount() uint8 {265return *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().
270func (sid *SID) SubAuthority(idx uint32) uint32 {271if idx >= uint32(sid.SubAuthorityCount()) {272panic("sub-authority index out of range")273}274return *getSidSubAuthority(sid, idx)275}
276
277// IsValid returns whether the SID has a valid revision and length.
278func (sid *SID) IsValid() bool {279return isValidSid(sid)280}
281
282// Equals compares two SIDs for equality.
283func (sid *SID) Equals(sid2 *SID) bool {284return EqualSid(sid, sid2)285}
286
287// IsWellKnown determines whether the SID matches the well-known sidType.
288func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {289return 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.
295func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {296var sys *uint16297if len(system) > 0 {298sys, err = UTF16PtrFromString(system)299if err != nil {300return "", "", 0, err301}302}303n := uint32(50)304dn := uint32(50)305for {306b := make([]uint16, n)307db := make([]uint16, dn)308e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)309if e == nil {310return UTF16ToString(b), UTF16ToString(db), accType, nil311}312if e != ERROR_INSUFFICIENT_BUFFER {313return "", "", 0, e314}315if n <= uint32(len(b)) {316return "", "", 0, e317}318}319}
320
321// Various types of pre-specified SIDs that can be synthesized and compared at runtime.
322type WELL_KNOWN_SID_TYPE uint32323
324const (325WinNullSid = 0326WinWorldSid = 1327WinLocalSid = 2328WinCreatorOwnerSid = 3329WinCreatorGroupSid = 4330WinCreatorOwnerServerSid = 5331WinCreatorGroupServerSid = 6332WinNtAuthoritySid = 7333WinDialupSid = 8334WinNetworkSid = 9335WinBatchSid = 10336WinInteractiveSid = 11337WinServiceSid = 12338WinAnonymousSid = 13339WinProxySid = 14340WinEnterpriseControllersSid = 15341WinSelfSid = 16342WinAuthenticatedUserSid = 17343WinRestrictedCodeSid = 18344WinTerminalServerSid = 19345WinRemoteLogonIdSid = 20346WinLogonIdsSid = 21347WinLocalSystemSid = 22348WinLocalServiceSid = 23349WinNetworkServiceSid = 24350WinBuiltinDomainSid = 25351WinBuiltinAdministratorsSid = 26352WinBuiltinUsersSid = 27353WinBuiltinGuestsSid = 28354WinBuiltinPowerUsersSid = 29355WinBuiltinAccountOperatorsSid = 30356WinBuiltinSystemOperatorsSid = 31357WinBuiltinPrintOperatorsSid = 32358WinBuiltinBackupOperatorsSid = 33359WinBuiltinReplicatorSid = 34360WinBuiltinPreWindows2000CompatibleAccessSid = 35361WinBuiltinRemoteDesktopUsersSid = 36362WinBuiltinNetworkConfigurationOperatorsSid = 37363WinAccountAdministratorSid = 38364WinAccountGuestSid = 39365WinAccountKrbtgtSid = 40366WinAccountDomainAdminsSid = 41367WinAccountDomainUsersSid = 42368WinAccountDomainGuestsSid = 43369WinAccountComputersSid = 44370WinAccountControllersSid = 45371WinAccountCertAdminsSid = 46372WinAccountSchemaAdminsSid = 47373WinAccountEnterpriseAdminsSid = 48374WinAccountPolicyAdminsSid = 49375WinAccountRasAndIasServersSid = 50376WinNTLMAuthenticationSid = 51377WinDigestAuthenticationSid = 52378WinSChannelAuthenticationSid = 53379WinThisOrganizationSid = 54380WinOtherOrganizationSid = 55381WinBuiltinIncomingForestTrustBuildersSid = 56382WinBuiltinPerfMonitoringUsersSid = 57383WinBuiltinPerfLoggingUsersSid = 58384WinBuiltinAuthorizationAccessSid = 59385WinBuiltinTerminalServerLicenseServersSid = 60386WinBuiltinDCOMUsersSid = 61387WinBuiltinIUsersSid = 62388WinIUserSid = 63389WinBuiltinCryptoOperatorsSid = 64390WinUntrustedLabelSid = 65391WinLowLabelSid = 66392WinMediumLabelSid = 67393WinHighLabelSid = 68394WinSystemLabelSid = 69395WinWriteRestrictedCodeSid = 70396WinCreatorOwnerRightsSid = 71397WinCacheablePrincipalsGroupSid = 72398WinNonCacheablePrincipalsGroupSid = 73399WinEnterpriseReadonlyControllersSid = 74400WinAccountReadonlyControllersSid = 75401WinBuiltinEventLogReadersGroup = 76402WinNewEnterpriseReadonlyControllersSid = 77403WinBuiltinCertSvcDComAccessGroup = 78404WinMediumPlusLabelSid = 79405WinLocalLogonSid = 80406WinConsoleLogonSid = 81407WinThisOrganizationCertificateSid = 82408WinApplicationPackageAuthoritySid = 83409WinBuiltinAnyPackageSid = 84410WinCapabilityInternetClientSid = 85411WinCapabilityInternetClientServerSid = 86412WinCapabilityPrivateNetworkClientServerSid = 87413WinCapabilityPicturesLibrarySid = 88414WinCapabilityVideosLibrarySid = 89415WinCapabilityMusicLibrarySid = 90416WinCapabilityDocumentsLibrarySid = 91417WinCapabilitySharedUserCertificatesSid = 92418WinCapabilityEnterpriseAuthenticationSid = 93419WinCapabilityRemovableStorageSid = 94420WinBuiltinRDSRemoteAccessServersSid = 95421WinBuiltinRDSEndpointServersSid = 96422WinBuiltinRDSManagementServersSid = 97423WinUserModeDriversSid = 98424WinBuiltinHyperVAdminsSid = 99425WinAccountCloneableControllersSid = 100426WinBuiltinAccessControlAssistanceOperatorsSid = 101427WinBuiltinRemoteManagementUsersSid = 102428WinAuthenticationAuthorityAssertedSid = 103429WinAuthenticationServiceAssertedSid = 104430WinLocalAccountSid = 105431WinLocalAccountAndAdministratorSid = 106432WinAccountProtectedUsersSid = 107433WinCapabilityAppointmentsSid = 108434WinCapabilityContactsSid = 109435WinAccountDefaultSystemManagedSid = 110436WinBuiltinDefaultSystemManagedGroupSid = 111437WinBuiltinStorageReplicaAdminsSid = 112438WinAccountKeyAdminsSid = 113439WinAccountEnterpriseKeyAdminsSid = 114440WinAuthenticationKeyTrustSid = 115441WinAuthenticationKeyPropertyMFASid = 116442WinAuthenticationKeyPropertyAttestationSid = 117443WinAuthenticationFreshKeyAuthSid = 118444WinBuiltinDeviceOwnersSid = 119445)
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.
449func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {450return 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.
455func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {456n := uint32(50)457for {458b := make([]byte, n)459sid := (*SID)(unsafe.Pointer(&b[0]))460err := createWellKnownSid(sidType, domainSid, sid, &n)461if err == nil {462return sid, nil463}464if err != ERROR_INSUFFICIENT_BUFFER {465return nil, err466}467if n <= uint32(len(b)) {468return nil, err469}470}471}
472
473const (474// do not reorder475TOKEN_ASSIGN_PRIMARY = 1 << iota476TOKEN_DUPLICATE
477TOKEN_IMPERSONATE
478TOKEN_QUERY
479TOKEN_QUERY_SOURCE
480TOKEN_ADJUST_PRIVILEGES
481TOKEN_ADJUST_GROUPS
482TOKEN_ADJUST_DEFAULT
483TOKEN_ADJUST_SESSIONID
484
485TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |486TOKEN_ASSIGN_PRIMARY |487TOKEN_DUPLICATE |488TOKEN_IMPERSONATE |489TOKEN_QUERY |490TOKEN_QUERY_SOURCE |491TOKEN_ADJUST_PRIVILEGES |492TOKEN_ADJUST_GROUPS |493TOKEN_ADJUST_DEFAULT |494TOKEN_ADJUST_SESSIONID
495TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY496TOKEN_WRITE = STANDARD_RIGHTS_WRITE |497TOKEN_ADJUST_PRIVILEGES |498TOKEN_ADJUST_GROUPS |499TOKEN_ADJUST_DEFAULT
500TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE501)
502
503const (504// do not reorder505TokenUser = 1 + iota506TokenGroups
507TokenPrivileges
508TokenOwner
509TokenPrimaryGroup
510TokenDefaultDacl
511TokenSource
512TokenType
513TokenImpersonationLevel
514TokenStatistics
515TokenRestrictedSids
516TokenSessionId
517TokenGroupsAndPrivileges
518TokenSessionReference
519TokenSandBoxInert
520TokenAuditPolicy
521TokenOrigin
522TokenElevationType
523TokenLinkedToken
524TokenElevation
525TokenHasRestrictions
526TokenAccessInformation
527TokenVirtualizationAllowed
528TokenVirtualizationEnabled
529TokenIntegrityLevel
530TokenUIAccess
531TokenMandatoryPolicy
532TokenLogonSid
533MaxTokenInfoClass
534)
535
536// Group attributes inside of Tokengroups.Groups[i].Attributes
537const (538SE_GROUP_MANDATORY = 0x00000001539SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002540SE_GROUP_ENABLED = 0x00000004541SE_GROUP_OWNER = 0x00000008542SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010543SE_GROUP_INTEGRITY = 0x00000020544SE_GROUP_INTEGRITY_ENABLED = 0x00000040545SE_GROUP_LOGON_ID = 0xC0000000546SE_GROUP_RESOURCE = 0x20000000547SE_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_ENABLED548)
549
550// Privilege attributes
551const (552SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001553SE_PRIVILEGE_ENABLED = 0x00000002554SE_PRIVILEGE_REMOVED = 0x00000004555SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000556SE_PRIVILEGE_VALID_ATTRIBUTES = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS557)
558
559// Token types
560const (561TokenPrimary = 1562TokenImpersonation = 2563)
564
565// Impersonation levels
566const (567SecurityAnonymous = 0568SecurityIdentification = 1569SecurityImpersonation = 2570SecurityDelegation = 3571)
572
573type LUID struct {574LowPart uint32575HighPart int32576}
577
578type LUIDAndAttributes struct {579Luid LUID
580Attributes uint32581}
582
583type SIDAndAttributes struct {584Sid *SID585Attributes uint32586}
587
588type Tokenuser struct {589User SIDAndAttributes
590}
591
592type Tokenprimarygroup struct {593PrimaryGroup *SID594}
595
596type Tokengroups struct {597GroupCount uint32598Groups [1]SIDAndAttributes // Use AllGroups() for iterating.599}
600
601// AllGroups returns a slice that can be used to iterate over the groups in g.
602func (g *Tokengroups) AllGroups() []SIDAndAttributes {603return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]604}
605
606type Tokenprivileges struct {607PrivilegeCount uint32608Privileges [1]LUIDAndAttributes // Use AllPrivileges() for iterating.609}
610
611// AllPrivileges returns a slice that can be used to iterate over the privileges in p.
612func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {613return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]614}
615
616type Tokenmandatorylabel struct {617Label SIDAndAttributes
618}
619
620func (tml *Tokenmandatorylabel) Size() uint32 {621return 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.
650type Token Handle651
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.
658func OpenCurrentProcessToken() (Token, error) {659var token Token660err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token)661return token, err662}
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.
667func GetCurrentProcessToken() Token {668return 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.
674func GetCurrentThreadToken() Token {675return 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.
681func GetCurrentThreadEffectiveToken() Token {682return Token(^uintptr(6 - 1))683}
684
685// Close releases access to access token.
686func (t Token) Close() error {687return CloseHandle(Handle(t))688}
689
690// getInfo retrieves a specified type of information about an access token.
691func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {692n := uint32(initSize)693for {694b := make([]byte, n)695e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)696if e == nil {697return unsafe.Pointer(&b[0]), nil698}699if e != ERROR_INSUFFICIENT_BUFFER {700return nil, e701}702if n <= uint32(len(b)) {703return nil, e704}705}706}
707
708// GetTokenUser retrieves access token t user account information.
709func (t Token) GetTokenUser() (*Tokenuser, error) {710i, e := t.getInfo(TokenUser, 50)711if e != nil {712return nil, e713}714return (*Tokenuser)(i), nil715}
716
717// GetTokenGroups retrieves group accounts associated with access token t.
718func (t Token) GetTokenGroups() (*Tokengroups, error) {719i, e := t.getInfo(TokenGroups, 50)720if e != nil {721return nil, e722}723return (*Tokengroups)(i), nil724}
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.
729func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {730i, e := t.getInfo(TokenPrimaryGroup, 50)731if e != nil {732return nil, e733}734return (*Tokenprimarygroup)(i), nil735}
736
737// GetUserProfileDirectory retrieves path to the
738// root directory of the access token t user's profile.
739func (t Token) GetUserProfileDirectory() (string, error) {740n := uint32(100)741for {742b := make([]uint16, n)743e := GetUserProfileDirectory(t, &b[0], &n)744if e == nil {745return UTF16ToString(b), nil746}747if e != ERROR_INSUFFICIENT_BUFFER {748return "", e749}750if n <= uint32(len(b)) {751return "", e752}753}754}
755
756// IsElevated returns whether the current token is elevated from a UAC perspective.
757func (token Token) IsElevated() bool {758var isElevated uint32759var outLen uint32760err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)761if err != nil {762return false763}764return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0765}
766
767// GetLinkedToken returns the linked token, which may be an elevated UAC token.
768func (token Token) GetLinkedToken() (Token, error) {769var linkedToken Token770var outLen uint32771err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)772if err != nil {773return Token(0), err774}775return linkedToken, nil776}
777
778// GetSystemDirectory retrieves the path to current location of the system
779// directory, which is typically, though not always, `C:\Windows\System32`.
780func GetSystemDirectory() (string, error) {781n := uint32(MAX_PATH)782for {783b := make([]uint16, n)784l, e := getSystemDirectory(&b[0], n)785if e != nil {786return "", e787}788if l <= n {789return UTF16ToString(b[:l]), nil790}791n = l792}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.
799func GetWindowsDirectory() (string, error) {800n := uint32(MAX_PATH)801for {802b := make([]uint16, n)803l, e := getWindowsDirectory(&b[0], n)804if e != nil {805return "", e806}807if l <= n {808return UTF16ToString(b[:l]), nil809}810n = l811}812}
813
814// GetSystemWindowsDirectory retrieves the path to current location of the
815// Windows directory, which is typically, though not always, `C:\Windows`.
816func GetSystemWindowsDirectory() (string, error) {817n := uint32(MAX_PATH)818for {819b := make([]uint16, n)820l, e := getSystemWindowsDirectory(&b[0], n)821if e != nil {822return "", e823}824if l <= n {825return UTF16ToString(b[:l]), nil826}827n = l828}829}
830
831// IsMember reports whether the access token t is a member of the provided SID.
832func (t Token) IsMember(sid *SID) (bool, error) {833var b int32834if e := checkTokenMembership(t, sid, &b); e != nil {835return false, e836}837return b != 0, nil838}
839
840// IsRestricted reports whether the access token t is a restricted token.
841func (t Token) IsRestricted() (isRestricted bool, err error) {842isRestricted, err = isTokenRestricted(t)843if !isRestricted && err == syscall.EINVAL {844// If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token.845err = nil846}847return848}
849
850const (851WTS_CONSOLE_CONNECT = 0x1852WTS_CONSOLE_DISCONNECT = 0x2853WTS_REMOTE_CONNECT = 0x3854WTS_REMOTE_DISCONNECT = 0x4855WTS_SESSION_LOGON = 0x5856WTS_SESSION_LOGOFF = 0x6857WTS_SESSION_LOCK = 0x7858WTS_SESSION_UNLOCK = 0x8859WTS_SESSION_REMOTE_CONTROL = 0x9860WTS_SESSION_CREATE = 0xa861WTS_SESSION_TERMINATE = 0xb862)
863
864const (865WTSActive = 0866WTSConnected = 1867WTSConnectQuery = 2868WTSShadow = 3869WTSDisconnected = 4870WTSIdle = 5871WTSListen = 6872WTSReset = 7873WTSDown = 8874WTSInit = 9875)
876
877type WTSSESSION_NOTIFICATION struct {878Size uint32879SessionID uint32880}
881
882type WTS_SESSION_INFO struct {883SessionID uint32884WindowStationName *uint16885State uint32886}
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
893type ACL struct {894aclRevision byte895sbz1 byte896aclSize uint16897AceCount uint16898sbz2 uint16899}
900
901type SECURITY_DESCRIPTOR struct {902revision byte903sbz1 byte904control SECURITY_DESCRIPTOR_CONTROL
905owner *SID906group *SID907sacl *ACL908dacl *ACL909}
910
911type SECURITY_QUALITY_OF_SERVICE struct {912Length uint32913ImpersonationLevel uint32914ContextTrackingMode byte915EffectiveOnly byte916}
917
918// Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
919const (920SECURITY_STATIC_TRACKING = 0921SECURITY_DYNAMIC_TRACKING = 1922)
923
924type SecurityAttributes struct {925Length uint32926SecurityDescriptor *SECURITY_DESCRIPTOR927InheritHandle uint32928}
929
930type SE_OBJECT_TYPE uint32931
932// Constants for type SE_OBJECT_TYPE
933const (934SE_UNKNOWN_OBJECT_TYPE = 0935SE_FILE_OBJECT = 1936SE_SERVICE = 2937SE_PRINTER = 3938SE_REGISTRY_KEY = 4939SE_LMSHARE = 5940SE_KERNEL_OBJECT = 6941SE_WINDOW_OBJECT = 7942SE_DS_OBJECT = 8943SE_DS_OBJECT_ALL = 9944SE_PROVIDER_DEFINED_OBJECT = 10945SE_WMIGUID_OBJECT = 11946SE_REGISTRY_WOW64_32KEY = 12947SE_REGISTRY_WOW64_64KEY = 13948)
949
950type SECURITY_INFORMATION uint32951
952// Constants for type SECURITY_INFORMATION
953const (954OWNER_SECURITY_INFORMATION = 0x00000001955GROUP_SECURITY_INFORMATION = 0x00000002956DACL_SECURITY_INFORMATION = 0x00000004957SACL_SECURITY_INFORMATION = 0x00000008958LABEL_SECURITY_INFORMATION = 0x00000010959ATTRIBUTE_SECURITY_INFORMATION = 0x00000020960SCOPE_SECURITY_INFORMATION = 0x00000040961BACKUP_SECURITY_INFORMATION = 0x00010000962PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000963PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000964UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000965UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000966)
967
968type SECURITY_DESCRIPTOR_CONTROL uint16969
970// Constants for type SECURITY_DESCRIPTOR_CONTROL
971const (972SE_OWNER_DEFAULTED = 0x0001973SE_GROUP_DEFAULTED = 0x0002974SE_DACL_PRESENT = 0x0004975SE_DACL_DEFAULTED = 0x0008976SE_SACL_PRESENT = 0x0010977SE_SACL_DEFAULTED = 0x0020978SE_DACL_AUTO_INHERIT_REQ = 0x0100979SE_SACL_AUTO_INHERIT_REQ = 0x0200980SE_DACL_AUTO_INHERITED = 0x0400981SE_SACL_AUTO_INHERITED = 0x0800982SE_DACL_PROTECTED = 0x1000983SE_SACL_PROTECTED = 0x2000984SE_RM_CONTROL_VALID = 0x4000985SE_SELF_RELATIVE = 0x8000986)
987
988type ACCESS_MASK uint32989
990// Constants for type ACCESS_MASK
991const (992DELETE = 0x00010000993READ_CONTROL = 0x00020000994WRITE_DAC = 0x00040000995WRITE_OWNER = 0x00080000996SYNCHRONIZE = 0x00100000997STANDARD_RIGHTS_REQUIRED = 0x000F0000998STANDARD_RIGHTS_READ = READ_CONTROL999STANDARD_RIGHTS_WRITE = READ_CONTROL1000STANDARD_RIGHTS_EXECUTE = READ_CONTROL1001STANDARD_RIGHTS_ALL = 0x001F00001002SPECIFIC_RIGHTS_ALL = 0x0000FFFF1003ACCESS_SYSTEM_SECURITY = 0x010000001004MAXIMUM_ALLOWED = 0x020000001005GENERIC_READ = 0x800000001006GENERIC_WRITE = 0x400000001007GENERIC_EXECUTE = 0x200000001008GENERIC_ALL = 0x100000001009)
1010
1011type ACCESS_MODE uint321012
1013// Constants for type ACCESS_MODE
1014const (1015NOT_USED_ACCESS = 01016GRANT_ACCESS = 11017SET_ACCESS = 21018DENY_ACCESS = 31019REVOKE_ACCESS = 41020SET_AUDIT_SUCCESS = 51021SET_AUDIT_FAILURE = 61022)
1023
1024// Constants for AceFlags and Inheritance fields
1025const (1026NO_INHERITANCE = 0x01027SUB_OBJECTS_ONLY_INHERIT = 0x11028SUB_CONTAINERS_ONLY_INHERIT = 0x21029SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x31030INHERIT_NO_PROPAGATE = 0x41031INHERIT_ONLY = 0x81032INHERITED_ACCESS_ENTRY = 0x101033INHERITED_PARENT = 0x100000001034INHERITED_GRANDPARENT = 0x200000001035OBJECT_INHERIT_ACE = 0x11036CONTAINER_INHERIT_ACE = 0x21037NO_PROPAGATE_INHERIT_ACE = 0x41038INHERIT_ONLY_ACE = 0x81039INHERITED_ACE = 0x101040VALID_INHERIT_FLAGS = 0x1F1041)
1042
1043type MULTIPLE_TRUSTEE_OPERATION uint321044
1045// Constants for MULTIPLE_TRUSTEE_OPERATION
1046const (1047NO_MULTIPLE_TRUSTEE = 01048TRUSTEE_IS_IMPERSONATE = 11049)
1050
1051type TRUSTEE_FORM uint321052
1053// Constants for TRUSTEE_FORM
1054const (1055TRUSTEE_IS_SID = 01056TRUSTEE_IS_NAME = 11057TRUSTEE_BAD_FORM = 21058TRUSTEE_IS_OBJECTS_AND_SID = 31059TRUSTEE_IS_OBJECTS_AND_NAME = 41060)
1061
1062type TRUSTEE_TYPE uint321063
1064// Constants for TRUSTEE_TYPE
1065const (1066TRUSTEE_IS_UNKNOWN = 01067TRUSTEE_IS_USER = 11068TRUSTEE_IS_GROUP = 21069TRUSTEE_IS_DOMAIN = 31070TRUSTEE_IS_ALIAS = 41071TRUSTEE_IS_WELL_KNOWN_GROUP = 51072TRUSTEE_IS_DELETED = 61073TRUSTEE_IS_INVALID = 71074TRUSTEE_IS_COMPUTER = 81075)
1076
1077// Constants for ObjectsPresent field
1078const (1079ACE_OBJECT_TYPE_PRESENT = 0x11080ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x21081)
1082
1083type EXPLICIT_ACCESS struct {1084AccessPermissions ACCESS_MASK
1085AccessMode ACCESS_MODE
1086Inheritance uint321087Trustee TRUSTEE
1088}
1089
1090// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
1091type ACE_HEADER struct {1092AceType uint81093AceFlags uint81094AceSize uint161095}
1096
1097// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
1098type ACCESS_ALLOWED_ACE struct {1099Header ACE_HEADER
1100Mask ACCESS_MASK
1101SidStart uint321102}
1103
1104const (1105// Constants for AceType1106// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header1107ACCESS_ALLOWED_ACE_TYPE = 01108ACCESS_DENIED_ACE_TYPE = 11109)
1110
1111// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
1112type TrusteeValue uintptr1113
1114func TrusteeValueFromString(str string) TrusteeValue {1115return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))1116}
1117func TrusteeValueFromSID(sid *SID) TrusteeValue {1118return TrusteeValue(unsafe.Pointer(sid))1119}
1120func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {1121return TrusteeValue(unsafe.Pointer(objectsAndSid))1122}
1123func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {1124return TrusteeValue(unsafe.Pointer(objectsAndName))1125}
1126
1127type TRUSTEE struct {1128MultipleTrustee *TRUSTEE1129MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
1130TrusteeForm TRUSTEE_FORM
1131TrusteeType TRUSTEE_TYPE
1132TrusteeValue TrusteeValue
1133}
1134
1135type OBJECTS_AND_SID struct {1136ObjectsPresent uint321137ObjectTypeGuid GUID
1138InheritedObjectTypeGuid GUID
1139Sid *SID1140}
1141
1142type OBJECTS_AND_NAME struct {1143ObjectsPresent uint321144ObjectType SE_OBJECT_TYPE
1145ObjectTypeName *uint161146InheritedObjectTypeName *uint161147Name *uint161148}
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.
1185func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {1186err = getSecurityDescriptorControl(sd, &control, &revision)1187return1188}
1189
1190// SetControl sets the security descriptor control bits.
1191func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {1192return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)1193}
1194
1195// RMControl returns the security descriptor resource manager control bits.
1196func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {1197err = getSecurityDescriptorRMControl(sd, &control)1198return1199}
1200
1201// SetRMControl sets the security descriptor resource manager control bits.
1202func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {1203setSecurityDescriptorRMControl(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.
1209func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {1210var present bool1211err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)1212if !present {1213err = ERROR_OBJECT_NOT_FOUND1214}1215return1216}
1217
1218// SetDACL sets the absolute security descriptor DACL.
1219func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {1220return 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.
1226func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {1227var present bool1228err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)1229if !present {1230err = ERROR_OBJECT_NOT_FOUND1231}1232return1233}
1234
1235// SetSACL sets the absolute security descriptor SACL.
1236func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {1237return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)1238}
1239
1240// Owner returns the security descriptor owner and whether it was defaulted.
1241func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {1242err = getSecurityDescriptorOwner(sd, &owner, &defaulted)1243return1244}
1245
1246// SetOwner sets the absolute security descriptor owner.
1247func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {1248return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)1249}
1250
1251// Group returns the security descriptor group and whether it was defaulted.
1252func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {1253err = getSecurityDescriptorGroup(sd, &group, &defaulted)1254return1255}
1256
1257// SetGroup sets the absolute security descriptor owner.
1258func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {1259return setSecurityDescriptorGroup(absoluteSD, group, defaulted)1260}
1261
1262// Length returns the length of the security descriptor.
1263func (sd *SECURITY_DESCRIPTOR) Length() uint32 {1264return getSecurityDescriptorLength(sd)1265}
1266
1267// IsValid returns whether the security descriptor is valid.
1268func (sd *SECURITY_DESCRIPTOR) IsValid() bool {1269return 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.
1274func (sd *SECURITY_DESCRIPTOR) String() string {1275var sddl *uint161276err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)1277if err != nil {1278return ""1279}1280defer LocalFree(Handle(unsafe.Pointer(sddl)))1281return UTF16PtrToString(sddl)1282}
1283
1284// ToAbsolute converts a self-relative security descriptor into an absolute one.
1285func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {1286control, _, err := selfRelativeSD.Control()1287if err != nil {1288return1289}1290if control&SE_SELF_RELATIVE == 0 {1291err = ERROR_INVALID_PARAMETER1292return1293}1294var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint321295err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,1296nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)1297switch err {1298case ERROR_INSUFFICIENT_BUFFER:1299case nil:1300// makeAbsoluteSD is expected to fail, but it succeeds.1301return nil, ERROR_INTERNAL_ERROR1302default:1303return nil, err1304}1305if absoluteSDSize > 0 {1306absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))1307}1308var (1309dacl *ACL1310sacl *ACL1311owner *SID1312group *SID1313)1314if daclSize > 0 {1315dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))1316}1317if saclSize > 0 {1318sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))1319}1320if ownerSize > 0 {1321owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))1322}1323if groupSize > 0 {1324group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))1325}1326err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,1327dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)1328return1329}
1330
1331// ToSelfRelative converts an absolute security descriptor into a self-relative one.
1332func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {1333control, _, err := absoluteSD.Control()1334if err != nil {1335return1336}1337if control&SE_SELF_RELATIVE != 0 {1338err = ERROR_INVALID_PARAMETER1339return1340}1341var selfRelativeSDSize uint321342err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)1343switch err {1344case ERROR_INSUFFICIENT_BUFFER:1345case nil:1346// makeSelfRelativeSD is expected to fail, but it succeeds.1347return nil, ERROR_INTERNAL_ERROR1348default:1349return nil, err1350}1351if selfRelativeSDSize > 0 {1352selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))1353}1354err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)1355return1356}
1357
1358func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {1359sdLen := int(selfRelativeSD.Length())1360const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))1361if sdLen < min {1362sdLen = min1363}1364
1365src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen)1366// SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to1367// be aligned properly. When we're copying a Windows-allocated struct to a1368// Go-allocated one, make sure that the Go allocation is aligned to the1369// pointer size.1370const psize = int(unsafe.Sizeof(uintptr(0)))1371alloc := make([]uintptr, (sdLen+psize-1)/psize)1372dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen)1373copy(dst, src)1374return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))1375}
1376
1377// SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
1378// self-relative security descriptor object allocated on the Go heap.
1379func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {1380var winHeapSD *SECURITY_DESCRIPTOR1381err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)1382if err != nil {1383return1384}1385defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))1386return winHeapSD.copySelfRelativeSecurityDescriptor(), nil1387}
1388
1389// GetSecurityInfo queries the security information for a given handle and returns the self-relative security
1390// descriptor result on the Go heap.
1391func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {1392var winHeapSD *SECURITY_DESCRIPTOR1393err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)1394if err != nil {1395return1396}1397defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))1398return winHeapSD.copySelfRelativeSecurityDescriptor(), nil1399}
1400
1401// GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
1402// descriptor result on the Go heap.
1403func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {1404var winHeapSD *SECURITY_DESCRIPTOR1405err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)1406if err != nil {1407return1408}1409defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))1410return winHeapSD.copySelfRelativeSecurityDescriptor(), nil1411}
1412
1413// BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
1414// prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
1415// result on the Go heap.
1416func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {1417var winHeapSD *SECURITY_DESCRIPTOR1418var winHeapSDSize uint321419var firstAccessEntry *EXPLICIT_ACCESS1420if len(accessEntries) > 0 {1421firstAccessEntry = &accessEntries[0]1422}1423var firstAuditEntry *EXPLICIT_ACCESS1424if len(auditEntries) > 0 {1425firstAuditEntry = &auditEntries[0]1426}1427err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)1428if err != nil {1429return1430}1431defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))1432return winHeapSD.copySelfRelativeSecurityDescriptor(), nil1433}
1434
1435// NewSecurityDescriptor creates and initializes a new absolute security descriptor.
1436func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {1437absoluteSD = &SECURITY_DESCRIPTOR{}1438err = initializeSecurityDescriptor(absoluteSD, 1)1439return1440}
1441
1442// ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
1443// Both explicitEntries and mergedACL are optional and can be nil.
1444func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {1445var firstExplicitEntry *EXPLICIT_ACCESS1446if len(explicitEntries) > 0 {1447firstExplicitEntry = &explicitEntries[0]1448}1449var winHeapACL *ACL1450err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)1451if err != nil {1452return1453}1454defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))1455aclBytes := make([]byte, winHeapACL.aclSize)1456copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])1457return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil1458}
1459