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 }