OSDN Git Service

bd40fe5867605e6415947108ef2f4de2bb41903f
[pf3gnuchains/gcc-fork.git] / libgo / go / syscall / security_windows.go
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
5 package syscall
6
7 import (
8         "unsafe"
9 )
10
11 const (
12         STANDARD_RIGHTS_REQUIRED = 0xf0000
13         STANDARD_RIGHTS_READ     = 0x20000
14         STANDARD_RIGHTS_WRITE    = 0x20000
15         STANDARD_RIGHTS_EXECUTE  = 0x20000
16         STANDARD_RIGHTS_ALL      = 0x1F0000
17 )
18
19 const (
20         NameUnknown          = 0
21         NameFullyQualifiedDN = 1
22         NameSamCompatible    = 2
23         NameDisplay          = 3
24         NameUniqueId         = 6
25         NameCanonical        = 7
26         NameUserPrincipal    = 8
27         NameCanonicalEx      = 9
28         NameServicePrincipal = 10
29         NameDnsDomain        = 12
30 )
31
32 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
33 // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
34 //sys   TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
35 //sys   GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
36
37 // TranslateAccountName converts a directory service
38 // object name from one format to another.
39 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
40         u := StringToUTF16Ptr(username)
41         b := make([]uint16, 50)
42         n := uint32(len(b))
43         e := TranslateName(u, from, to, &b[0], &n)
44         if e != nil {
45                 if e != ERROR_INSUFFICIENT_BUFFER {
46                         return "", e
47                 }
48                 // make receive buffers of requested size and try again
49                 b = make([]uint16, n)
50                 e = TranslateName(u, from, to, &b[0], &n)
51                 if e != nil {
52                         return "", e
53                 }
54         }
55         return UTF16ToString(b), nil
56 }
57
58 type UserInfo10 struct {
59         Name       *uint16
60         Comment    *uint16
61         UsrComment *uint16
62         FullName   *uint16
63 }
64
65 //sys   NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
66 //sys   NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
67
68 const (
69         // do not reorder
70         SidTypeUser = 1 << iota
71         SidTypeGroup
72         SidTypeDomain
73         SidTypeAlias
74         SidTypeWellKnownGroup
75         SidTypeDeletedAccount
76         SidTypeInvalid
77         SidTypeUnknown
78         SidTypeComputer
79         SidTypeLabel
80 )
81
82 //sys   LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
83 //sys   LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
84 //sys   ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
85 //sys   ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
86 //sys   GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
87 //sys   CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
88
89 // The security identifier (SID) structure is a variable-length
90 // structure used to uniquely identify users or groups.
91 type SID struct{}
92
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         e := ConvertStringSidToSid(StringToUTF16Ptr(s), &sid)
98         if e != nil {
99                 return nil, e
100         }
101         defer LocalFree((Handle)(unsafe.Pointer(sid)))
102         return sid.Copy()
103 }
104
105 // LookupSID retrieves a security identifier sid for the account
106 // and the name of the domain on which the account was found.
107 // System specify target computer to search.
108 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
109         if len(account) == 0 {
110                 return nil, "", 0, EINVAL
111         }
112         acc := StringToUTF16Ptr(account)
113         var sys *uint16
114         if len(system) > 0 {
115                 sys = StringToUTF16Ptr(system)
116         }
117         db := make([]uint16, 50)
118         dn := uint32(len(db))
119         b := make([]byte, 50)
120         n := uint32(len(b))
121         sid = (*SID)(unsafe.Pointer(&b[0]))
122         e := LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
123         if e != nil {
124                 if e != ERROR_INSUFFICIENT_BUFFER {
125                         return nil, "", 0, e
126                 }
127                 // make receive buffers of requested size and try again
128                 b = make([]byte, n)
129                 sid = (*SID)(unsafe.Pointer(&b[0]))
130                 db = make([]uint16, dn)
131                 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
132                 if e != nil {
133                         return nil, "", 0, e
134                 }
135         }
136         return sid, UTF16ToString(db), accType, nil
137 }
138
139 // String converts sid to a string format
140 // suitable for display, storage, or transmission.
141 func (sid *SID) String() (string, error) {
142         var s *uint16
143         e := ConvertSidToStringSid(sid, &s)
144         if e != nil {
145                 return "", e
146         }
147         defer LocalFree((Handle)(unsafe.Pointer(s)))
148         return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
149 }
150
151 // Len returns the length, in bytes, of a valid security identifier sid.
152 func (sid *SID) Len() int {
153         return int(GetLengthSid(sid))
154 }
155
156 // Copy creates a duplicate of security identifier sid.
157 func (sid *SID) Copy() (*SID, error) {
158         b := make([]byte, sid.Len())
159         sid2 := (*SID)(unsafe.Pointer(&b[0]))
160         e := CopySid(uint32(len(b)), sid2, sid)
161         if e != nil {
162                 return nil, e
163         }
164         return sid2, nil
165 }
166
167 // LookupAccount retrieves the name of the account for this sid
168 // and the name of the first domain on which this sid is found.
169 // System specify target computer to search for.
170 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
171         var sys *uint16
172         if len(system) > 0 {
173                 sys = StringToUTF16Ptr(system)
174         }
175         b := make([]uint16, 50)
176         n := uint32(len(b))
177         db := make([]uint16, 50)
178         dn := uint32(len(db))
179         e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
180         if e != nil {
181                 if e != ERROR_INSUFFICIENT_BUFFER {
182                         return "", "", 0, e
183                 }
184                 // make receive buffers of requested size and try again
185                 b = make([]uint16, n)
186                 db = make([]uint16, dn)
187                 e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
188                 if e != nil {
189                         return "", "", 0, e
190                 }
191         }
192         return UTF16ToString(b), UTF16ToString(db), accType, nil
193 }
194
195 const (
196         // do not reorder
197         TOKEN_ASSIGN_PRIMARY = 1 << iota
198         TOKEN_DUPLICATE
199         TOKEN_IMPERSONATE
200         TOKEN_QUERY
201         TOKEN_QUERY_SOURCE
202         TOKEN_ADJUST_PRIVILEGES
203         TOKEN_ADJUST_GROUPS
204         TOKEN_ADJUST_DEFAULT
205
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
223 const (
224         // do not reorder
225         TokenUser = 1 + iota
226         TokenGroups
227         TokenPrivileges
228         TokenOwner
229         TokenPrimaryGroup
230         TokenDefaultDacl
231         TokenSource
232         TokenType
233         TokenImpersonationLevel
234         TokenStatistics
235         TokenRestrictedSids
236         TokenSessionId
237         TokenGroupsAndPrivileges
238         TokenSessionReference
239         TokenSandBoxInert
240         TokenAuditPolicy
241         TokenOrigin
242         TokenElevationType
243         TokenLinkedToken
244         TokenElevation
245         TokenHasRestrictions
246         TokenAccessInformation
247         TokenVirtualizationAllowed
248         TokenVirtualizationEnabled
249         TokenIntegrityLevel
250         TokenUIAccess
251         TokenMandatoryPolicy
252         TokenLogonSid
253         MaxTokenInfoClass
254 )
255
256 type SIDAndAttributes struct {
257         Sid        *SID
258         Attributes uint32
259 }
260
261 type Tokenuser struct {
262         User SIDAndAttributes
263 }
264
265 type Tokenprimarygroup struct {
266         PrimaryGroup *SID
267 }
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
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
282 // OpenCurrentProcessToken opens the access token
283 // associated with current process.
284 func OpenCurrentProcessToken() (Token, error) {
285         p, e := GetCurrentProcess()
286         if e != nil {
287                 return 0, e
288         }
289         var t Token
290         e = OpenProcessToken(p, TOKEN_QUERY, &t)
291         if e != nil {
292                 return 0, e
293         }
294         return t, nil
295 }
296
297 // Close releases access to access token.
298 func (t Token) Close() error {
299         return CloseHandle(Handle(t))
300 }
301
302 // getInfo retrieves a specified type of information about an access token.
303 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
304         b := make([]byte, initSize)
305         var n uint32
306         e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
307         if e != nil {
308                 if e != ERROR_INSUFFICIENT_BUFFER {
309                         return nil, e
310                 }
311                 // make receive buffers of requested size and try again
312                 b = make([]byte, n)
313                 e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
314                 if e != nil {
315                         return nil, e
316                 }
317         }
318         return unsafe.Pointer(&b[0]), nil
319 }
320
321 // GetTokenUser retrieves access token t user account information.
322 func (t Token) GetTokenUser() (*Tokenuser, error) {
323         i, e := t.getInfo(TokenUser, 50)
324         if e != nil {
325                 return nil, e
326         }
327         return (*Tokenuser)(i), nil
328 }
329
330 // GetTokenPrimaryGroup retrieves access token t primary group information.
331 // A pointer to a SID structure representing a group that will become
332 // the primary group of any objects created by a process using this access token.
333 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
334         i, e := t.getInfo(TokenPrimaryGroup, 50)
335         if e != nil {
336                 return nil, e
337         }
338         return (*Tokenprimarygroup)(i), nil
339 }
340
341 // GetUserProfileDirectory retrieves path to the
342 // root directory of the access token t user's profile.
343 func (t Token) GetUserProfileDirectory() (string, error) {
344         b := make([]uint16, 100)
345         n := uint32(len(b))
346         e := GetUserProfileDirectory(t, &b[0], &n)
347         if e != nil {
348                 if e != ERROR_INSUFFICIENT_BUFFER {
349                         return "", e
350                 }
351                 // make receive buffers of requested size and try again
352                 b = make([]uint16, n)
353                 e = GetUserProfileDirectory(t, &b[0], &n)
354                 if e != nil {
355                         return "", e
356                 }
357         }
358         return UTF16ToString(b), nil
359 }