github.com/tristanisham/sys@v0.0.0-20240326010300-a16cbabb7555/windows/security_windows.go (about)

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