OSDN Git Service

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