security_windows.go 11 KB

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