You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

security_windows.go 31KB

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