1// Copyright 2012 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package windows 6 7import ( 8 "syscall" 9 "unsafe" 10) 11 12const ( 13 STANDARD_RIGHTS_REQUIRED = 0xf0000 14 STANDARD_RIGHTS_READ = 0x20000 15 STANDARD_RIGHTS_WRITE = 0x20000 16 STANDARD_RIGHTS_EXECUTE = 0x20000 17 STANDARD_RIGHTS_ALL = 0x1F0000 18) 19 20const ( 21 NameUnknown = 0 22 NameFullyQualifiedDN = 1 23 NameSamCompatible = 2 24 NameDisplay = 3 25 NameUniqueId = 6 26 NameCanonical = 7 27 NameUserPrincipal = 8 28 NameCanonicalEx = 9 29 NameServicePrincipal = 10 30 NameDnsDomain = 12 31) 32 33// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. 34// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx 35//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW 36//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW 37 38// TranslateAccountName converts a directory service 39// object name from one format to another. 40func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { 41 u, e := UTF16PtrFromString(username) 42 if e != nil { 43 return "", e 44 } 45 n := uint32(50) 46 for { 47 b := make([]uint16, n) 48 e = TranslateName(u, from, to, &b[0], &n) 49 if e == nil { 50 return UTF16ToString(b[:n]), nil 51 } 52 if e != ERROR_INSUFFICIENT_BUFFER { 53 return "", e 54 } 55 if n <= uint32(len(b)) { 56 return "", e 57 } 58 } 59} 60 61const ( 62 // do not reorder 63 NetSetupUnknownStatus = iota 64 NetSetupUnjoined 65 NetSetupWorkgroupName 66 NetSetupDomainName 67) 68 69type UserInfo10 struct { 70 Name *uint16 71 Comment *uint16 72 UsrComment *uint16 73 FullName *uint16 74} 75 76//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo 77//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation 78//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree 79 80const ( 81 // do not reorder 82 SidTypeUser = 1 + iota 83 SidTypeGroup 84 SidTypeDomain 85 SidTypeAlias 86 SidTypeWellKnownGroup 87 SidTypeDeletedAccount 88 SidTypeInvalid 89 SidTypeUnknown 90 SidTypeComputer 91 SidTypeLabel 92) 93 94type SidIdentifierAuthority struct { 95 Value [6]byte 96} 97 98var ( 99 SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}} 100 SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}} 101 SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}} 102 SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}} 103 SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}} 104 SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}} 105 SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}} 106) 107 108const ( 109 SECURITY_NULL_RID = 0 110 SECURITY_WORLD_RID = 0 111 SECURITY_LOCAL_RID = 0 112 SECURITY_CREATOR_OWNER_RID = 0 113 SECURITY_CREATOR_GROUP_RID = 1 114 SECURITY_DIALUP_RID = 1 115 SECURITY_NETWORK_RID = 2 116 SECURITY_BATCH_RID = 3 117 SECURITY_INTERACTIVE_RID = 4 118 SECURITY_LOGON_IDS_RID = 5 119 SECURITY_SERVICE_RID = 6 120 SECURITY_LOCAL_SYSTEM_RID = 18 121 SECURITY_BUILTIN_DOMAIN_RID = 32 122 SECURITY_PRINCIPAL_SELF_RID = 10 123 SECURITY_CREATOR_OWNER_SERVER_RID = 0x2 124 SECURITY_CREATOR_GROUP_SERVER_RID = 0x3 125 SECURITY_LOGON_IDS_RID_COUNT = 0x3 126 SECURITY_ANONYMOUS_LOGON_RID = 0x7 127 SECURITY_PROXY_RID = 0x8 128 SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9 129 SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID 130 SECURITY_AUTHENTICATED_USER_RID = 0xb 131 SECURITY_RESTRICTED_CODE_RID = 0xc 132 SECURITY_NT_NON_UNIQUE_RID = 0x15 133) 134 135// Predefined domain-relative RIDs for local groups. 136// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx 137const ( 138 DOMAIN_ALIAS_RID_ADMINS = 0x220 139 DOMAIN_ALIAS_RID_USERS = 0x221 140 DOMAIN_ALIAS_RID_GUESTS = 0x222 141 DOMAIN_ALIAS_RID_POWER_USERS = 0x223 142 DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224 143 DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225 144 DOMAIN_ALIAS_RID_PRINT_OPS = 0x226 145 DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227 146 DOMAIN_ALIAS_RID_REPLICATOR = 0x228 147 DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229 148 DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a 149 DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b 150 DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c 151 DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d 152 DOMAIN_ALIAS_RID_MONITORING_USERS = 0x22e 153 DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f 154 DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 155 DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 156 DOMAIN_ALIAS_RID_DCOM_USERS = 0x232 157 DOMAIN_ALIAS_RID_IUSERS = 0x238 158 DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239 159 DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b 160 DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c 161 DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d 162 DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e 163) 164 165//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW 166//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW 167//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW 168//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW 169//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid 170//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid 171//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 172//sys createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid 173//sys isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid 174//sys FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid 175//sys EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid 176//sys getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority 177//sys getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount 178//sys getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority 179//sys isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid 180 181// The security identifier (SID) structure is a variable-length 182// structure used to uniquely identify users or groups. 183type SID struct{} 184 185// StringToSid converts a string-format security identifier 186// SID into a valid, functional SID. 187func StringToSid(s string) (*SID, error) { 188 var sid *SID 189 p, e := UTF16PtrFromString(s) 190 if e != nil { 191 return nil, e 192 } 193 e = ConvertStringSidToSid(p, &sid) 194 if e != nil { 195 return nil, e 196 } 197 defer LocalFree((Handle)(unsafe.Pointer(sid))) 198 return sid.Copy() 199} 200 201// LookupSID retrieves a security identifier SID for the account 202// and the name of the domain on which the account was found. 203// System specify target computer to search. 204func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { 205 if len(account) == 0 { 206 return nil, "", 0, syscall.EINVAL 207 } 208 acc, e := UTF16PtrFromString(account) 209 if e != nil { 210 return nil, "", 0, e 211 } 212 var sys *uint16 213 if len(system) > 0 { 214 sys, e = UTF16PtrFromString(system) 215 if e != nil { 216 return nil, "", 0, e 217 } 218 } 219 n := uint32(50) 220 dn := uint32(50) 221 for { 222 b := make([]byte, n) 223 db := make([]uint16, dn) 224 sid = (*SID)(unsafe.Pointer(&b[0])) 225 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) 226 if e == nil { 227 return sid, UTF16ToString(db), accType, nil 228 } 229 if e != ERROR_INSUFFICIENT_BUFFER { 230 return nil, "", 0, e 231 } 232 if n <= uint32(len(b)) { 233 return nil, "", 0, e 234 } 235 } 236} 237 238// String converts SID to a string format 239// suitable for display, storage, or transmission. 240func (sid *SID) String() (string, error) { 241 var s *uint16 242 e := ConvertSidToStringSid(sid, &s) 243 if e != nil { 244 return "", e 245 } 246 defer LocalFree((Handle)(unsafe.Pointer(s))) 247 return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil 248} 249 250// Len returns the length, in bytes, of a valid security identifier SID. 251func (sid *SID) Len() int { 252 return int(GetLengthSid(sid)) 253} 254 255// Copy creates a duplicate of security identifier SID. 256func (sid *SID) Copy() (*SID, error) { 257 b := make([]byte, sid.Len()) 258 sid2 := (*SID)(unsafe.Pointer(&b[0])) 259 e := CopySid(uint32(len(b)), sid2, sid) 260 if e != nil { 261 return nil, e 262 } 263 return sid2, nil 264} 265 266// IdentifierAuthority returns the identifier authority of the SID. 267func (sid *SID) IdentifierAuthority() SidIdentifierAuthority { 268 return *getSidIdentifierAuthority(sid) 269} 270 271// SubAuthorityCount returns the number of sub-authorities in the SID. 272func (sid *SID) SubAuthorityCount() uint8 { 273 return *getSidSubAuthorityCount(sid) 274} 275 276// SubAuthority returns the sub-authority of the SID as specified by 277// the index, which must be less than sid.SubAuthorityCount(). 278func (sid *SID) SubAuthority(idx uint32) uint32 { 279 if idx >= uint32(sid.SubAuthorityCount()) { 280 panic("sub-authority index out of range") 281 } 282 return *getSidSubAuthority(sid, idx) 283} 284 285// IsValid returns whether the SID has a valid revision and length. 286func (sid *SID) IsValid() bool { 287 return isValidSid(sid) 288} 289 290// Equals compares two SIDs for equality. 291func (sid *SID) Equals(sid2 *SID) bool { 292 return EqualSid(sid, sid2) 293} 294 295// IsWellKnown determines whether the SID matches the well-known sidType. 296func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool { 297 return isWellKnownSid(sid, sidType) 298} 299 300// LookupAccount retrieves the name of the account for this SID 301// and the name of the first domain on which this SID is found. 302// System specify target computer to search for. 303func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { 304 var sys *uint16 305 if len(system) > 0 { 306 sys, err = UTF16PtrFromString(system) 307 if err != nil { 308 return "", "", 0, err 309 } 310 } 311 n := uint32(50) 312 dn := uint32(50) 313 for { 314 b := make([]uint16, n) 315 db := make([]uint16, dn) 316 e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) 317 if e == nil { 318 return UTF16ToString(b), UTF16ToString(db), accType, nil 319 } 320 if e != ERROR_INSUFFICIENT_BUFFER { 321 return "", "", 0, e 322 } 323 if n <= uint32(len(b)) { 324 return "", "", 0, e 325 } 326 } 327} 328 329// Various types of pre-specified SIDs that can be synthesized and compared at runtime. 330type WELL_KNOWN_SID_TYPE uint32 331 332const ( 333 WinNullSid = 0 334 WinWorldSid = 1 335 WinLocalSid = 2 336 WinCreatorOwnerSid = 3 337 WinCreatorGroupSid = 4 338 WinCreatorOwnerServerSid = 5 339 WinCreatorGroupServerSid = 6 340 WinNtAuthoritySid = 7 341 WinDialupSid = 8 342 WinNetworkSid = 9 343 WinBatchSid = 10 344 WinInteractiveSid = 11 345 WinServiceSid = 12 346 WinAnonymousSid = 13 347 WinProxySid = 14 348 WinEnterpriseControllersSid = 15 349 WinSelfSid = 16 350 WinAuthenticatedUserSid = 17 351 WinRestrictedCodeSid = 18 352 WinTerminalServerSid = 19 353 WinRemoteLogonIdSid = 20 354 WinLogonIdsSid = 21 355 WinLocalSystemSid = 22 356 WinLocalServiceSid = 23 357 WinNetworkServiceSid = 24 358 WinBuiltinDomainSid = 25 359 WinBuiltinAdministratorsSid = 26 360 WinBuiltinUsersSid = 27 361 WinBuiltinGuestsSid = 28 362 WinBuiltinPowerUsersSid = 29 363 WinBuiltinAccountOperatorsSid = 30 364 WinBuiltinSystemOperatorsSid = 31 365 WinBuiltinPrintOperatorsSid = 32 366 WinBuiltinBackupOperatorsSid = 33 367 WinBuiltinReplicatorSid = 34 368 WinBuiltinPreWindows2000CompatibleAccessSid = 35 369 WinBuiltinRemoteDesktopUsersSid = 36 370 WinBuiltinNetworkConfigurationOperatorsSid = 37 371 WinAccountAdministratorSid = 38 372 WinAccountGuestSid = 39 373 WinAccountKrbtgtSid = 40 374 WinAccountDomainAdminsSid = 41 375 WinAccountDomainUsersSid = 42 376 WinAccountDomainGuestsSid = 43 377 WinAccountComputersSid = 44 378 WinAccountControllersSid = 45 379 WinAccountCertAdminsSid = 46 380 WinAccountSchemaAdminsSid = 47 381 WinAccountEnterpriseAdminsSid = 48 382 WinAccountPolicyAdminsSid = 49 383 WinAccountRasAndIasServersSid = 50 384 WinNTLMAuthenticationSid = 51 385 WinDigestAuthenticationSid = 52 386 WinSChannelAuthenticationSid = 53 387 WinThisOrganizationSid = 54 388 WinOtherOrganizationSid = 55 389 WinBuiltinIncomingForestTrustBuildersSid = 56 390 WinBuiltinPerfMonitoringUsersSid = 57 391 WinBuiltinPerfLoggingUsersSid = 58 392 WinBuiltinAuthorizationAccessSid = 59 393 WinBuiltinTerminalServerLicenseServersSid = 60 394 WinBuiltinDCOMUsersSid = 61 395 WinBuiltinIUsersSid = 62 396 WinIUserSid = 63 397 WinBuiltinCryptoOperatorsSid = 64 398 WinUntrustedLabelSid = 65 399 WinLowLabelSid = 66 400 WinMediumLabelSid = 67 401 WinHighLabelSid = 68 402 WinSystemLabelSid = 69 403 WinWriteRestrictedCodeSid = 70 404 WinCreatorOwnerRightsSid = 71 405 WinCacheablePrincipalsGroupSid = 72 406 WinNonCacheablePrincipalsGroupSid = 73 407 WinEnterpriseReadonlyControllersSid = 74 408 WinAccountReadonlyControllersSid = 75 409 WinBuiltinEventLogReadersGroup = 76 410 WinNewEnterpriseReadonlyControllersSid = 77 411 WinBuiltinCertSvcDComAccessGroup = 78 412 WinMediumPlusLabelSid = 79 413 WinLocalLogonSid = 80 414 WinConsoleLogonSid = 81 415 WinThisOrganizationCertificateSid = 82 416 WinApplicationPackageAuthoritySid = 83 417 WinBuiltinAnyPackageSid = 84 418 WinCapabilityInternetClientSid = 85 419 WinCapabilityInternetClientServerSid = 86 420 WinCapabilityPrivateNetworkClientServerSid = 87 421 WinCapabilityPicturesLibrarySid = 88 422 WinCapabilityVideosLibrarySid = 89 423 WinCapabilityMusicLibrarySid = 90 424 WinCapabilityDocumentsLibrarySid = 91 425 WinCapabilitySharedUserCertificatesSid = 92 426 WinCapabilityEnterpriseAuthenticationSid = 93 427 WinCapabilityRemovableStorageSid = 94 428 WinBuiltinRDSRemoteAccessServersSid = 95 429 WinBuiltinRDSEndpointServersSid = 96 430 WinBuiltinRDSManagementServersSid = 97 431 WinUserModeDriversSid = 98 432 WinBuiltinHyperVAdminsSid = 99 433 WinAccountCloneableControllersSid = 100 434 WinBuiltinAccessControlAssistanceOperatorsSid = 101 435 WinBuiltinRemoteManagementUsersSid = 102 436 WinAuthenticationAuthorityAssertedSid = 103 437 WinAuthenticationServiceAssertedSid = 104 438 WinLocalAccountSid = 105 439 WinLocalAccountAndAdministratorSid = 106 440 WinAccountProtectedUsersSid = 107 441 WinCapabilityAppointmentsSid = 108 442 WinCapabilityContactsSid = 109 443 WinAccountDefaultSystemManagedSid = 110 444 WinBuiltinDefaultSystemManagedGroupSid = 111 445 WinBuiltinStorageReplicaAdminsSid = 112 446 WinAccountKeyAdminsSid = 113 447 WinAccountEnterpriseKeyAdminsSid = 114 448 WinAuthenticationKeyTrustSid = 115 449 WinAuthenticationKeyPropertyMFASid = 116 450 WinAuthenticationKeyPropertyAttestationSid = 117 451 WinAuthenticationFreshKeyAuthSid = 118 452 WinBuiltinDeviceOwnersSid = 119 453) 454 455// Creates a SID for a well-known predefined alias, generally using the constants of the form 456// Win*Sid, for the local machine. 457func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) { 458 return CreateWellKnownDomainSid(sidType, nil) 459} 460 461// Creates a SID for a well-known predefined alias, generally using the constants of the form 462// Win*Sid, for the domain specified by the domainSid parameter. 463func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) { 464 n := uint32(50) 465 for { 466 b := make([]byte, n) 467 sid := (*SID)(unsafe.Pointer(&b[0])) 468 err := createWellKnownSid(sidType, domainSid, sid, &n) 469 if err == nil { 470 return sid, nil 471 } 472 if err != ERROR_INSUFFICIENT_BUFFER { 473 return nil, err 474 } 475 if n <= uint32(len(b)) { 476 return nil, err 477 } 478 } 479} 480 481const ( 482 // do not reorder 483 TOKEN_ASSIGN_PRIMARY = 1 << iota 484 TOKEN_DUPLICATE 485 TOKEN_IMPERSONATE 486 TOKEN_QUERY 487 TOKEN_QUERY_SOURCE 488 TOKEN_ADJUST_PRIVILEGES 489 TOKEN_ADJUST_GROUPS 490 TOKEN_ADJUST_DEFAULT 491 TOKEN_ADJUST_SESSIONID 492 493 TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | 494 TOKEN_ASSIGN_PRIMARY | 495 TOKEN_DUPLICATE | 496 TOKEN_IMPERSONATE | 497 TOKEN_QUERY | 498 TOKEN_QUERY_SOURCE | 499 TOKEN_ADJUST_PRIVILEGES | 500 TOKEN_ADJUST_GROUPS | 501 TOKEN_ADJUST_DEFAULT | 502 TOKEN_ADJUST_SESSIONID 503 TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY 504 TOKEN_WRITE = STANDARD_RIGHTS_WRITE | 505 TOKEN_ADJUST_PRIVILEGES | 506 TOKEN_ADJUST_GROUPS | 507 TOKEN_ADJUST_DEFAULT 508 TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE 509) 510 511const ( 512 // do not reorder 513 TokenUser = 1 + iota 514 TokenGroups 515 TokenPrivileges 516 TokenOwner 517 TokenPrimaryGroup 518 TokenDefaultDacl 519 TokenSource 520 TokenType 521 TokenImpersonationLevel 522 TokenStatistics 523 TokenRestrictedSids 524 TokenSessionId 525 TokenGroupsAndPrivileges 526 TokenSessionReference 527 TokenSandBoxInert 528 TokenAuditPolicy 529 TokenOrigin 530 TokenElevationType 531 TokenLinkedToken 532 TokenElevation 533 TokenHasRestrictions 534 TokenAccessInformation 535 TokenVirtualizationAllowed 536 TokenVirtualizationEnabled 537 TokenIntegrityLevel 538 TokenUIAccess 539 TokenMandatoryPolicy 540 TokenLogonSid 541 MaxTokenInfoClass 542) 543 544// Group attributes inside of Tokengroups.Groups[i].Attributes 545const ( 546 SE_GROUP_MANDATORY = 0x00000001 547 SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002 548 SE_GROUP_ENABLED = 0x00000004 549 SE_GROUP_OWNER = 0x00000008 550 SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010 551 SE_GROUP_INTEGRITY = 0x00000020 552 SE_GROUP_INTEGRITY_ENABLED = 0x00000040 553 SE_GROUP_LOGON_ID = 0xC0000000 554 SE_GROUP_RESOURCE = 0x20000000 555 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 556) 557 558// Privilege attributes 559const ( 560 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001 561 SE_PRIVILEGE_ENABLED = 0x00000002 562 SE_PRIVILEGE_REMOVED = 0x00000004 563 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000 564 SE_PRIVILEGE_VALID_ATTRIBUTES = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS 565) 566 567// Token types 568const ( 569 TokenPrimary = 1 570 TokenImpersonation = 2 571) 572 573// Impersonation levels 574const ( 575 SecurityAnonymous = 0 576 SecurityIdentification = 1 577 SecurityImpersonation = 2 578 SecurityDelegation = 3 579) 580 581type LUID struct { 582 LowPart uint32 583 HighPart int32 584} 585 586type LUIDAndAttributes struct { 587 Luid LUID 588 Attributes uint32 589} 590 591type SIDAndAttributes struct { 592 Sid *SID 593 Attributes uint32 594} 595 596type Tokenuser struct { 597 User SIDAndAttributes 598} 599 600type Tokenprimarygroup struct { 601 PrimaryGroup *SID 602} 603 604type Tokengroups struct { 605 GroupCount uint32 606 Groups [1]SIDAndAttributes // Use AllGroups() for iterating. 607} 608 609// AllGroups returns a slice that can be used to iterate over the groups in g. 610func (g *Tokengroups) AllGroups() []SIDAndAttributes { 611 return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount] 612} 613 614type Tokenprivileges struct { 615 PrivilegeCount uint32 616 Privileges [1]LUIDAndAttributes // Use AllPrivileges() for iterating. 617} 618 619// AllPrivileges returns a slice that can be used to iterate over the privileges in p. 620func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes { 621 return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount] 622} 623 624type Tokenmandatorylabel struct { 625 Label SIDAndAttributes 626} 627 628func (tml *Tokenmandatorylabel) Size() uint32 { 629 return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid) 630} 631 632// Authorization Functions 633//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership 634//sys OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken 635//sys OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken 636//sys ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf 637//sys RevertToSelf() (err error) = advapi32.RevertToSelf 638//sys SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken 639//sys LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW 640//sys AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges 641//sys AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups 642//sys GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation 643//sys SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation 644//sys DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx 645//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW 646//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW 647 648// An access token contains the security information for a logon session. 649// The system creates an access token when a user logs on, and every 650// process executed on behalf of the user has a copy of the token. 651// The token identifies the user, the user's groups, and the user's 652// privileges. The system uses the token to control access to securable 653// objects and to control the ability of the user to perform various 654// system-related operations on the local computer. 655type Token Handle 656 657// OpenCurrentProcessToken opens the access token 658// associated with current process. It is a real 659// token that needs to be closed, unlike 660// GetCurrentProcessToken. 661func OpenCurrentProcessToken() (Token, error) { 662 p, e := GetCurrentProcess() 663 if e != nil { 664 return 0, e 665 } 666 var t Token 667 e = OpenProcessToken(p, TOKEN_QUERY, &t) 668 if e != nil { 669 return 0, e 670 } 671 return t, nil 672} 673 674// GetCurrentProcessToken returns the access token associated with 675// the current process. It is a pseudo token that does not need 676// to be closed. 677func GetCurrentProcessToken() Token { 678 return Token(^uintptr(4 - 1)) 679} 680 681// GetCurrentThreadToken return the access token associated with 682// the current thread. It is a pseudo token that does not need 683// to be closed. 684func GetCurrentThreadToken() Token { 685 return Token(^uintptr(5 - 1)) 686} 687 688// GetCurrentThreadEffectiveToken returns the effective access token 689// associated with the current thread. It is a pseudo token that does 690// not need to be closed. 691func GetCurrentThreadEffectiveToken() Token { 692 return Token(^uintptr(6 - 1)) 693} 694 695// Close releases access to access token. 696func (t Token) Close() error { 697 return CloseHandle(Handle(t)) 698} 699 700// getInfo retrieves a specified type of information about an access token. 701func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { 702 n := uint32(initSize) 703 for { 704 b := make([]byte, n) 705 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) 706 if e == nil { 707 return unsafe.Pointer(&b[0]), nil 708 } 709 if e != ERROR_INSUFFICIENT_BUFFER { 710 return nil, e 711 } 712 if n <= uint32(len(b)) { 713 return nil, e 714 } 715 } 716} 717 718// GetTokenUser retrieves access token t user account information. 719func (t Token) GetTokenUser() (*Tokenuser, error) { 720 i, e := t.getInfo(TokenUser, 50) 721 if e != nil { 722 return nil, e 723 } 724 return (*Tokenuser)(i), nil 725} 726 727// GetTokenGroups retrieves group accounts associated with access token t. 728func (t Token) GetTokenGroups() (*Tokengroups, error) { 729 i, e := t.getInfo(TokenGroups, 50) 730 if e != nil { 731 return nil, e 732 } 733 return (*Tokengroups)(i), nil 734} 735 736// GetTokenPrimaryGroup retrieves access token t primary group information. 737// A pointer to a SID structure representing a group that will become 738// the primary group of any objects created by a process using this access token. 739func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { 740 i, e := t.getInfo(TokenPrimaryGroup, 50) 741 if e != nil { 742 return nil, e 743 } 744 return (*Tokenprimarygroup)(i), nil 745} 746 747// GetUserProfileDirectory retrieves path to the 748// root directory of the access token t user's profile. 749func (t Token) GetUserProfileDirectory() (string, error) { 750 n := uint32(100) 751 for { 752 b := make([]uint16, n) 753 e := GetUserProfileDirectory(t, &b[0], &n) 754 if e == nil { 755 return UTF16ToString(b), nil 756 } 757 if e != ERROR_INSUFFICIENT_BUFFER { 758 return "", e 759 } 760 if n <= uint32(len(b)) { 761 return "", e 762 } 763 } 764} 765 766// IsElevated returns whether the current token is elevated from a UAC perspective. 767func (token Token) IsElevated() bool { 768 var isElevated uint32 769 var outLen uint32 770 err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen) 771 if err != nil { 772 return false 773 } 774 return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0 775} 776 777// GetLinkedToken returns the linked token, which may be an elevated UAC token. 778func (token Token) GetLinkedToken() (Token, error) { 779 var linkedToken Token 780 var outLen uint32 781 err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen) 782 if err != nil { 783 return Token(0), err 784 } 785 return linkedToken, nil 786} 787 788// GetSystemDirectory retrieves path to current location of the system 789// directory, which is typically, though not always, C:\Windows\System32. 790func GetSystemDirectory() (string, error) { 791 n := uint32(MAX_PATH) 792 for { 793 b := make([]uint16, n) 794 l, e := getSystemDirectory(&b[0], n) 795 if e != nil { 796 return "", e 797 } 798 if l <= n { 799 return UTF16ToString(b[:l]), nil 800 } 801 n = l 802 } 803} 804 805// IsMember reports whether the access token t is a member of the provided SID. 806func (t Token) IsMember(sid *SID) (bool, error) { 807 var b int32 808 if e := checkTokenMembership(t, sid, &b); e != nil { 809 return false, e 810 } 811 return b != 0, nil 812} 813 814const ( 815 WTS_CONSOLE_CONNECT = 0x1 816 WTS_CONSOLE_DISCONNECT = 0x2 817 WTS_REMOTE_CONNECT = 0x3 818 WTS_REMOTE_DISCONNECT = 0x4 819 WTS_SESSION_LOGON = 0x5 820 WTS_SESSION_LOGOFF = 0x6 821 WTS_SESSION_LOCK = 0x7 822 WTS_SESSION_UNLOCK = 0x8 823 WTS_SESSION_REMOTE_CONTROL = 0x9 824 WTS_SESSION_CREATE = 0xa 825 WTS_SESSION_TERMINATE = 0xb 826) 827 828const ( 829 WTSActive = 0 830 WTSConnected = 1 831 WTSConnectQuery = 2 832 WTSShadow = 3 833 WTSDisconnected = 4 834 WTSIdle = 5 835 WTSListen = 6 836 WTSReset = 7 837 WTSDown = 8 838 WTSInit = 9 839) 840 841type WTSSESSION_NOTIFICATION struct { 842 Size uint32 843 SessionID uint32 844} 845 846type WTS_SESSION_INFO struct { 847 SessionID uint32 848 WindowStationName *uint16 849 State uint32 850} 851 852//sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken 853//sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW 854//sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory 855