security_windows.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. //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, syscall.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. n := uint32(50)
  126. dn := uint32(50)
  127. for {
  128. b := make([]byte, n)
  129. db := make([]uint16, dn)
  130. sid = (*SID)(unsafe.Pointer(&b[0]))
  131. e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
  132. if e == nil {
  133. return sid, UTF16ToString(db), accType, nil
  134. }
  135. if e != ERROR_INSUFFICIENT_BUFFER {
  136. return nil, "", 0, e
  137. }
  138. if n <= uint32(len(b)) {
  139. return nil, "", 0, e
  140. }
  141. }
  142. }
  143. // String converts sid to a string format
  144. // suitable for display, storage, or transmission.
  145. func (sid *SID) String() (string, error) {
  146. var s *uint16
  147. e := ConvertSidToStringSid(sid, &s)
  148. if e != nil {
  149. return "", e
  150. }
  151. defer LocalFree((Handle)(unsafe.Pointer(s)))
  152. return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
  153. }
  154. // Len returns the length, in bytes, of a valid security identifier sid.
  155. func (sid *SID) Len() int {
  156. return int(GetLengthSid(sid))
  157. }
  158. // Copy creates a duplicate of security identifier sid.
  159. func (sid *SID) Copy() (*SID, error) {
  160. b := make([]byte, sid.Len())
  161. sid2 := (*SID)(unsafe.Pointer(&b[0]))
  162. e := CopySid(uint32(len(b)), sid2, sid)
  163. if e != nil {
  164. return nil, e
  165. }
  166. return sid2, nil
  167. }
  168. // LookupAccount retrieves the name of the account for this sid
  169. // and the name of the first domain on which this sid is found.
  170. // System specify target computer to search for.
  171. func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
  172. var sys *uint16
  173. if len(system) > 0 {
  174. sys, err = UTF16PtrFromString(system)
  175. if err != nil {
  176. return "", "", 0, err
  177. }
  178. }
  179. n := uint32(50)
  180. dn := uint32(50)
  181. for {
  182. b := make([]uint16, n)
  183. db := make([]uint16, dn)
  184. e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
  185. if e == nil {
  186. return UTF16ToString(b), UTF16ToString(db), accType, nil
  187. }
  188. if e != ERROR_INSUFFICIENT_BUFFER {
  189. return "", "", 0, e
  190. }
  191. if n <= uint32(len(b)) {
  192. return "", "", 0, e
  193. }
  194. }
  195. }
  196. const (
  197. // do not reorder
  198. TOKEN_ASSIGN_PRIMARY = 1 << iota
  199. TOKEN_DUPLICATE
  200. TOKEN_IMPERSONATE
  201. TOKEN_QUERY
  202. TOKEN_QUERY_SOURCE
  203. TOKEN_ADJUST_PRIVILEGES
  204. TOKEN_ADJUST_GROUPS
  205. TOKEN_ADJUST_DEFAULT
  206. TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
  207. TOKEN_ASSIGN_PRIMARY |
  208. TOKEN_DUPLICATE |
  209. TOKEN_IMPERSONATE |
  210. TOKEN_QUERY |
  211. TOKEN_QUERY_SOURCE |
  212. TOKEN_ADJUST_PRIVILEGES |
  213. TOKEN_ADJUST_GROUPS |
  214. TOKEN_ADJUST_DEFAULT
  215. TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
  216. TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
  217. TOKEN_ADJUST_PRIVILEGES |
  218. TOKEN_ADJUST_GROUPS |
  219. TOKEN_ADJUST_DEFAULT
  220. TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
  221. )
  222. const (
  223. // do not reorder
  224. TokenUser = 1 + iota
  225. TokenGroups
  226. TokenPrivileges
  227. TokenOwner
  228. TokenPrimaryGroup
  229. TokenDefaultDacl
  230. TokenSource
  231. TokenType
  232. TokenImpersonationLevel
  233. TokenStatistics
  234. TokenRestrictedSids
  235. TokenSessionId
  236. TokenGroupsAndPrivileges
  237. TokenSessionReference
  238. TokenSandBoxInert
  239. TokenAuditPolicy
  240. TokenOrigin
  241. TokenElevationType
  242. TokenLinkedToken
  243. TokenElevation
  244. TokenHasRestrictions
  245. TokenAccessInformation
  246. TokenVirtualizationAllowed
  247. TokenVirtualizationEnabled
  248. TokenIntegrityLevel
  249. TokenUIAccess
  250. TokenMandatoryPolicy
  251. TokenLogonSid
  252. MaxTokenInfoClass
  253. )
  254. type SIDAndAttributes struct {
  255. Sid *SID
  256. Attributes uint32
  257. }
  258. type Tokenuser struct {
  259. User SIDAndAttributes
  260. }
  261. type Tokenprimarygroup struct {
  262. PrimaryGroup *SID
  263. }
  264. //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
  265. //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
  266. //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
  267. // An access token contains the security information for a logon session.
  268. // The system creates an access token when a user logs on, and every
  269. // process executed on behalf of the user has a copy of the token.
  270. // The token identifies the user, the user's groups, and the user's
  271. // privileges. The system uses the token to control access to securable
  272. // objects and to control the ability of the user to perform various
  273. // system-related operations on the local computer.
  274. type Token Handle
  275. // OpenCurrentProcessToken opens the access token
  276. // associated with current process.
  277. func OpenCurrentProcessToken() (Token, error) {
  278. p, e := GetCurrentProcess()
  279. if e != nil {
  280. return 0, e
  281. }
  282. var t Token
  283. e = OpenProcessToken(p, TOKEN_QUERY, &t)
  284. if e != nil {
  285. return 0, e
  286. }
  287. return t, nil
  288. }
  289. // Close releases access to access token.
  290. func (t Token) Close() error {
  291. return CloseHandle(Handle(t))
  292. }
  293. // getInfo retrieves a specified type of information about an access token.
  294. func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
  295. n := uint32(initSize)
  296. for {
  297. b := make([]byte, n)
  298. e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
  299. if e == nil {
  300. return unsafe.Pointer(&b[0]), nil
  301. }
  302. if e != ERROR_INSUFFICIENT_BUFFER {
  303. return nil, e
  304. }
  305. if n <= uint32(len(b)) {
  306. return nil, e
  307. }
  308. }
  309. }
  310. // GetTokenUser retrieves access token t user account information.
  311. func (t Token) GetTokenUser() (*Tokenuser, error) {
  312. i, e := t.getInfo(TokenUser, 50)
  313. if e != nil {
  314. return nil, e
  315. }
  316. return (*Tokenuser)(i), nil
  317. }
  318. // GetTokenPrimaryGroup retrieves access token t primary group information.
  319. // A pointer to a SID structure representing a group that will become
  320. // the primary group of any objects created by a process using this access token.
  321. func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
  322. i, e := t.getInfo(TokenPrimaryGroup, 50)
  323. if e != nil {
  324. return nil, e
  325. }
  326. return (*Tokenprimarygroup)(i), nil
  327. }
  328. // GetUserProfileDirectory retrieves path to the
  329. // root directory of the access token t user's profile.
  330. func (t Token) GetUserProfileDirectory() (string, error) {
  331. n := uint32(100)
  332. for {
  333. b := make([]uint16, n)
  334. e := GetUserProfileDirectory(t, &b[0], &n)
  335. if e == nil {
  336. return UTF16ToString(b), nil
  337. }
  338. if e != ERROR_INSUFFICIENT_BUFFER {
  339. return "", e
  340. }
  341. if n <= uint32(len(b)) {
  342. return "", e
  343. }
  344. }
  345. }