security_windows.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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. "unsafe"
  7. )
  8. const (
  9. STANDARD_RIGHTS_REQUIRED = 0xf0000
  10. STANDARD_RIGHTS_READ = 0x20000
  11. STANDARD_RIGHTS_WRITE = 0x20000
  12. STANDARD_RIGHTS_EXECUTE = 0x20000
  13. STANDARD_RIGHTS_ALL = 0x1F0000
  14. )
  15. const (
  16. NameUnknown = 0
  17. NameFullyQualifiedDN = 1
  18. NameSamCompatible = 2
  19. NameDisplay = 3
  20. NameUniqueId = 6
  21. NameCanonical = 7
  22. NameUserPrincipal = 8
  23. NameCanonicalEx = 9
  24. NameServicePrincipal = 10
  25. NameDnsDomain = 12
  26. )
  27. // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
  28. // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
  29. //sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
  30. //sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
  31. // TranslateAccountName converts a directory service
  32. // object name from one format to another.
  33. func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
  34. u, e := UTF16PtrFromString(username)
  35. if e != nil {
  36. return "", e
  37. }
  38. b := make([]uint16, 50)
  39. n := uint32(len(b))
  40. e = TranslateName(u, from, to, &b[0], &n)
  41. if e != nil {
  42. if e != ERROR_INSUFFICIENT_BUFFER {
  43. return "", e
  44. }
  45. // make receive buffers of requested size and try again
  46. b = make([]uint16, n)
  47. e = TranslateName(u, from, to, &b[0], &n)
  48. if e != nil {
  49. return "", e
  50. }
  51. }
  52. return UTF16ToString(b), nil
  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. //sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
  84. //sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
  85. //sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
  86. //sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
  87. //sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
  88. //sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
  89. // The security identifier (SID) structure is a variable-length
  90. // structure used to uniquely identify users or groups.
  91. type SID struct{}
  92. // StringToSid converts a string-format security identifier
  93. // sid into a valid, functional sid.
  94. func StringToSid(s string) (*SID, error) {
  95. var sid *SID
  96. p, e := UTF16PtrFromString(s)
  97. if e != nil {
  98. return nil, e
  99. }
  100. e = ConvertStringSidToSid(p, &sid)
  101. if e != nil {
  102. return nil, e
  103. }
  104. defer LocalFree((Handle)(unsafe.Pointer(sid)))
  105. return sid.Copy()
  106. }
  107. // LookupSID retrieves a security identifier sid for the account
  108. // and the name of the domain on which the account was found.
  109. // System specify target computer to search.
  110. func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
  111. if len(account) == 0 {
  112. return nil, "", 0, EINVAL
  113. }
  114. acc, e := UTF16PtrFromString(account)
  115. if e != nil {
  116. return nil, "", 0, e
  117. }
  118. var sys *uint16
  119. if len(system) > 0 {
  120. sys, e = UTF16PtrFromString(system)
  121. if e != nil {
  122. return nil, "", 0, e
  123. }
  124. }
  125. db := make([]uint16, 50)
  126. dn := uint32(len(db))
  127. b := make([]byte, 50)
  128. n := uint32(len(b))
  129. sid = (*SID)(unsafe.Pointer(&b[0]))
  130. e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
  131. if e != nil {
  132. if e != ERROR_INSUFFICIENT_BUFFER {
  133. return nil, "", 0, e
  134. }
  135. // make receive buffers of requested size and try again
  136. b = make([]byte, n)
  137. sid = (*SID)(unsafe.Pointer(&b[0]))
  138. db = make([]uint16, dn)
  139. e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
  140. if e != nil {
  141. return nil, "", 0, e
  142. }
  143. }
  144. return sid, UTF16ToString(db), accType, nil
  145. }
  146. // String converts sid to a string format
  147. // suitable for display, storage, or transmission.
  148. func (sid *SID) String() (string, error) {
  149. var s *uint16
  150. e := ConvertSidToStringSid(sid, &s)
  151. if e != nil {
  152. return "", e
  153. }
  154. defer LocalFree((Handle)(unsafe.Pointer(s)))
  155. return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
  156. }
  157. // Len returns the length, in bytes, of a valid security identifier sid.
  158. func (sid *SID) Len() int {
  159. return int(GetLengthSid(sid))
  160. }
  161. // Copy creates a duplicate of security identifier sid.
  162. func (sid *SID) Copy() (*SID, error) {
  163. b := make([]byte, sid.Len())
  164. sid2 := (*SID)(unsafe.Pointer(&b[0]))
  165. e := CopySid(uint32(len(b)), sid2, sid)
  166. if e != nil {
  167. return nil, e
  168. }
  169. return sid2, nil
  170. }
  171. // LookupAccount retrieves the name of the account for this sid
  172. // and the name of the first domain on which this sid is found.
  173. // System specify target computer to search for.
  174. func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
  175. var sys *uint16
  176. if len(system) > 0 {
  177. sys, err = UTF16PtrFromString(system)
  178. if err != nil {
  179. return "", "", 0, err
  180. }
  181. }
  182. b := make([]uint16, 50)
  183. n := uint32(len(b))
  184. db := make([]uint16, 50)
  185. dn := uint32(len(db))
  186. e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
  187. if e != nil {
  188. if e != ERROR_INSUFFICIENT_BUFFER {
  189. return "", "", 0, e
  190. }
  191. // make receive buffers of requested size and try again
  192. b = make([]uint16, n)
  193. db = make([]uint16, dn)
  194. e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
  195. if e != nil {
  196. return "", "", 0, e
  197. }
  198. }
  199. return UTF16ToString(b), UTF16ToString(db), accType, nil
  200. }
  201. const (
  202. // do not reorder
  203. TOKEN_ASSIGN_PRIMARY = 1 << iota
  204. TOKEN_DUPLICATE
  205. TOKEN_IMPERSONATE
  206. TOKEN_QUERY
  207. TOKEN_QUERY_SOURCE
  208. TOKEN_ADJUST_PRIVILEGES
  209. TOKEN_ADJUST_GROUPS
  210. TOKEN_ADJUST_DEFAULT
  211. TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
  212. TOKEN_ASSIGN_PRIMARY |
  213. TOKEN_DUPLICATE |
  214. TOKEN_IMPERSONATE |
  215. TOKEN_QUERY |
  216. TOKEN_QUERY_SOURCE |
  217. TOKEN_ADJUST_PRIVILEGES |
  218. TOKEN_ADJUST_GROUPS |
  219. TOKEN_ADJUST_DEFAULT
  220. TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
  221. TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
  222. TOKEN_ADJUST_PRIVILEGES |
  223. TOKEN_ADJUST_GROUPS |
  224. TOKEN_ADJUST_DEFAULT
  225. TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
  226. )
  227. const (
  228. // do not reorder
  229. TokenUser = 1 + iota
  230. TokenGroups
  231. TokenPrivileges
  232. TokenOwner
  233. TokenPrimaryGroup
  234. TokenDefaultDacl
  235. TokenSource
  236. TokenType
  237. TokenImpersonationLevel
  238. TokenStatistics
  239. TokenRestrictedSids
  240. TokenSessionId
  241. TokenGroupsAndPrivileges
  242. TokenSessionReference
  243. TokenSandBoxInert
  244. TokenAuditPolicy
  245. TokenOrigin
  246. TokenElevationType
  247. TokenLinkedToken
  248. TokenElevation
  249. TokenHasRestrictions
  250. TokenAccessInformation
  251. TokenVirtualizationAllowed
  252. TokenVirtualizationEnabled
  253. TokenIntegrityLevel
  254. TokenUIAccess
  255. TokenMandatoryPolicy
  256. TokenLogonSid
  257. MaxTokenInfoClass
  258. )
  259. type SIDAndAttributes struct {
  260. Sid *SID
  261. Attributes uint32
  262. }
  263. type Tokenuser struct {
  264. User SIDAndAttributes
  265. }
  266. type Tokenprimarygroup struct {
  267. PrimaryGroup *SID
  268. }
  269. //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
  270. //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
  271. //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
  272. // An access token contains the security information for a logon session.
  273. // The system creates an access token when a user logs on, and every
  274. // process executed on behalf of the user has a copy of the token.
  275. // The token identifies the user, the user's groups, and the user's
  276. // privileges. The system uses the token to control access to securable
  277. // objects and to control the ability of the user to perform various
  278. // system-related operations on the local computer.
  279. type Token Handle
  280. // OpenCurrentProcessToken opens the access token
  281. // associated with current process.
  282. func OpenCurrentProcessToken() (Token, error) {
  283. p, e := GetCurrentProcess()
  284. if e != nil {
  285. return 0, e
  286. }
  287. var t Token
  288. e = OpenProcessToken(p, TOKEN_QUERY, &t)
  289. if e != nil {
  290. return 0, e
  291. }
  292. return t, nil
  293. }
  294. // Close releases access to access token.
  295. func (t Token) Close() error {
  296. return CloseHandle(Handle(t))
  297. }
  298. // getInfo retrieves a specified type of information about an access token.
  299. func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
  300. b := make([]byte, initSize)
  301. var n uint32
  302. e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
  303. if e != nil {
  304. if e != ERROR_INSUFFICIENT_BUFFER {
  305. return nil, e
  306. }
  307. // make receive buffers of requested size and try again
  308. b = make([]byte, n)
  309. e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
  310. if e != nil {
  311. return nil, e
  312. }
  313. }
  314. return unsafe.Pointer(&b[0]), nil
  315. }
  316. // GetTokenUser retrieves access token t user account information.
  317. func (t Token) GetTokenUser() (*Tokenuser, error) {
  318. i, e := t.getInfo(TokenUser, 50)
  319. if e != nil {
  320. return nil, e
  321. }
  322. return (*Tokenuser)(i), nil
  323. }
  324. // GetTokenPrimaryGroup retrieves access token t primary group information.
  325. // A pointer to a SID structure representing a group that will become
  326. // the primary group of any objects created by a process using this access token.
  327. func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
  328. i, e := t.getInfo(TokenPrimaryGroup, 50)
  329. if e != nil {
  330. return nil, e
  331. }
  332. return (*Tokenprimarygroup)(i), nil
  333. }
  334. // GetUserProfileDirectory retrieves path to the
  335. // root directory of the access token t user's profile.
  336. func (t Token) GetUserProfileDirectory() (string, error) {
  337. b := make([]uint16, 100)
  338. n := uint32(len(b))
  339. e := GetUserProfileDirectory(t, &b[0], &n)
  340. if e != nil {
  341. if e != ERROR_INSUFFICIENT_BUFFER {
  342. return "", e
  343. }
  344. // make receive buffers of requested size and try again
  345. b = make([]uint16, n)
  346. e = GetUserProfileDirectory(t, &b[0], &n)
  347. if e != nil {
  348. return "", e
  349. }
  350. }
  351. return UTF16ToString(b), nil
  352. }