~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/gabriel-samfira/sys/windows/security_windows.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 windows
 
6
 
 
7
import (
 
8
        "syscall"
 
9
        "unsafe"
 
10
)
 
11
 
 
12
const (
 
13
        STANDARD_RIGHTS_REQUIRED = 0xf0000
 
14
        STANDARD_RIGHTS_READ     = 0x20000
 
15
        STANDARD_RIGHTS_WRITE    = 0x20000
 
16
        STANDARD_RIGHTS_EXECUTE  = 0x20000
 
17
        STANDARD_RIGHTS_ALL      = 0x1F0000
 
18
)
 
19
 
 
20
const (
 
21
        NameUnknown          = 0
 
22
        NameFullyQualifiedDN = 1
 
23
        NameSamCompatible    = 2
 
24
        NameDisplay          = 3
 
25
        NameUniqueId         = 6
 
26
        NameCanonical        = 7
 
27
        NameUserPrincipal    = 8
 
28
        NameCanonicalEx      = 9
 
29
        NameServicePrincipal = 10
 
30
        NameDnsDomain        = 12
 
31
)
 
32
 
 
33
// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
 
34
// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
 
35
//sys   TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
 
36
//sys   GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
 
37
 
 
38
// TranslateAccountName converts a directory service
 
39
// object name from one format to another.
 
40
func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
 
41
        u, e := UTF16PtrFromString(username)
 
42
        if e != nil {
 
43
                return "", e
 
44
        }
 
45
        n := uint32(50)
 
46
        for {
 
47
                b := make([]uint16, n)
 
48
                e = TranslateName(u, from, to, &b[0], &n)
 
49
                if e == nil {
 
50
                        return UTF16ToString(b[:n]), nil
 
51
                }
 
52
                if e != ERROR_INSUFFICIENT_BUFFER {
 
53
                        return "", e
 
54
                }
 
55
                if n <= uint32(len(b)) {
 
56
                        return "", e
 
57
                }
 
58
        }
 
59
}
 
60
 
 
61
const (
 
62
        // do not reorder
 
63
        NetSetupUnknownStatus = iota
 
64
        NetSetupUnjoined
 
65
        NetSetupWorkgroupName
 
66
        NetSetupDomainName
 
67
)
 
68
 
 
69
type UserInfo10 struct {
 
70
        Name       *uint16
 
71
        Comment    *uint16
 
72
        UsrComment *uint16
 
73
        FullName   *uint16
 
74
}
 
75
 
 
76
//sys   NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
 
77
//sys   NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
 
78
//sys   NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
 
79
 
 
80
const (
 
81
        // do not reorder
 
82
        SidTypeUser = 1 + iota
 
83
        SidTypeGroup
 
84
        SidTypeDomain
 
85
        SidTypeAlias
 
86
        SidTypeWellKnownGroup
 
87
        SidTypeDeletedAccount
 
88
        SidTypeInvalid
 
89
        SidTypeUnknown
 
90
        SidTypeComputer
 
91
        SidTypeLabel
 
92
)
 
93
 
 
94
type SidIdentifierAuthority struct {
 
95
        Value [6]byte
 
96
}
 
97
 
 
98
var (
 
99
        SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
 
100
        SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
 
101
        SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
 
102
        SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
 
103
        SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
 
104
        SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
 
105
        SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
 
106
)
 
107
 
 
108
const (
 
109
        SECURITY_NULL_RID                   = 0
 
110
        SECURITY_WORLD_RID                  = 0
 
111
        SECURITY_LOCAL_RID                  = 0
 
112
        SECURITY_CREATOR_OWNER_RID          = 0
 
113
        SECURITY_CREATOR_GROUP_RID          = 1
 
114
        SECURITY_DIALUP_RID                 = 1
 
115
        SECURITY_NETWORK_RID                = 2
 
116
        SECURITY_BATCH_RID                  = 3
 
117
        SECURITY_INTERACTIVE_RID            = 4
 
118
        SECURITY_LOGON_IDS_RID              = 5
 
119
        SECURITY_SERVICE_RID                = 6
 
120
        SECURITY_LOCAL_SYSTEM_RID           = 18
 
121
        SECURITY_BUILTIN_DOMAIN_RID         = 32
 
122
        SECURITY_PRINCIPAL_SELF_RID         = 10
 
123
        SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
 
124
        SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
 
125
        SECURITY_LOGON_IDS_RID_COUNT        = 0x3
 
126
        SECURITY_ANONYMOUS_LOGON_RID        = 0x7
 
127
        SECURITY_PROXY_RID                  = 0x8
 
128
        SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
 
129
        SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
 
130
        SECURITY_AUTHENTICATED_USER_RID     = 0xb
 
131
        SECURITY_RESTRICTED_CODE_RID        = 0xc
 
132
        SECURITY_NT_NON_UNIQUE_RID          = 0x15
 
133
)
 
134
 
 
135
//sys   LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
 
136
//sys   LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
 
137
//sys   ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
 
138
//sys   ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
 
139
//sys   GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
 
140
//sys   CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
 
141
//sys   AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
 
142
//sys   FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
 
143
//sys   EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
 
144
 
 
145
// The security identifier (SID) structure is a variable-length
 
146
// structure used to uniquely identify users or groups.
 
147
type SID struct{}
 
148
 
 
149
// StringToSid converts a string-format security identifier
 
150
// sid into a valid, functional sid.
 
151
func StringToSid(s string) (*SID, error) {
 
152
        var sid *SID
 
153
        p, e := UTF16PtrFromString(s)
 
154
        if e != nil {
 
155
                return nil, e
 
156
        }
 
157
        e = ConvertStringSidToSid(p, &sid)
 
158
        if e != nil {
 
159
                return nil, e
 
160
        }
 
161
        defer LocalFree((Handle)(unsafe.Pointer(sid)))
 
162
        return sid.Copy()
 
163
}
 
164
 
 
165
// LookupSID retrieves a security identifier sid for the account
 
166
// and the name of the domain on which the account was found.
 
167
// System specify target computer to search.
 
168
func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
 
169
        if len(account) == 0 {
 
170
                return nil, "", 0, syscall.EINVAL
 
171
        }
 
172
        acc, e := UTF16PtrFromString(account)
 
173
        if e != nil {
 
174
                return nil, "", 0, e
 
175
        }
 
176
        var sys *uint16
 
177
        if len(system) > 0 {
 
178
                sys, e = UTF16PtrFromString(system)
 
179
                if e != nil {
 
180
                        return nil, "", 0, e
 
181
                }
 
182
        }
 
183
        n := uint32(50)
 
184
        dn := uint32(50)
 
185
        for {
 
186
                b := make([]byte, n)
 
187
                db := make([]uint16, dn)
 
188
                sid = (*SID)(unsafe.Pointer(&b[0]))
 
189
                e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
 
190
                if e == nil {
 
191
                        return sid, UTF16ToString(db), accType, nil
 
192
                }
 
193
                if e != ERROR_INSUFFICIENT_BUFFER {
 
194
                        return nil, "", 0, e
 
195
                }
 
196
                if n <= uint32(len(b)) {
 
197
                        return nil, "", 0, e
 
198
                }
 
199
        }
 
200
}
 
201
 
 
202
// String converts sid to a string format
 
203
// suitable for display, storage, or transmission.
 
204
func (sid *SID) String() (string, error) {
 
205
        var s *uint16
 
206
        e := ConvertSidToStringSid(sid, &s)
 
207
        if e != nil {
 
208
                return "", e
 
209
        }
 
210
        defer LocalFree((Handle)(unsafe.Pointer(s)))
 
211
        return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
 
212
}
 
213
 
 
214
// Len returns the length, in bytes, of a valid security identifier sid.
 
215
func (sid *SID) Len() int {
 
216
        return int(GetLengthSid(sid))
 
217
}
 
218
 
 
219
// Copy creates a duplicate of security identifier sid.
 
220
func (sid *SID) Copy() (*SID, error) {
 
221
        b := make([]byte, sid.Len())
 
222
        sid2 := (*SID)(unsafe.Pointer(&b[0]))
 
223
        e := CopySid(uint32(len(b)), sid2, sid)
 
224
        if e != nil {
 
225
                return nil, e
 
226
        }
 
227
        return sid2, nil
 
228
}
 
229
 
 
230
// LookupAccount retrieves the name of the account for this sid
 
231
// and the name of the first domain on which this sid is found.
 
232
// System specify target computer to search for.
 
233
func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
 
234
        var sys *uint16
 
235
        if len(system) > 0 {
 
236
                sys, err = UTF16PtrFromString(system)
 
237
                if err != nil {
 
238
                        return "", "", 0, err
 
239
                }
 
240
        }
 
241
        n := uint32(50)
 
242
        dn := uint32(50)
 
243
        for {
 
244
                b := make([]uint16, n)
 
245
                db := make([]uint16, dn)
 
246
                e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
 
247
                if e == nil {
 
248
                        return UTF16ToString(b), UTF16ToString(db), accType, nil
 
249
                }
 
250
                if e != ERROR_INSUFFICIENT_BUFFER {
 
251
                        return "", "", 0, e
 
252
                }
 
253
                if n <= uint32(len(b)) {
 
254
                        return "", "", 0, e
 
255
                }
 
256
        }
 
257
}
 
258
 
 
259
const (
 
260
        // do not reorder
 
261
        TOKEN_ASSIGN_PRIMARY = 1 << iota
 
262
        TOKEN_DUPLICATE
 
263
        TOKEN_IMPERSONATE
 
264
        TOKEN_QUERY
 
265
        TOKEN_QUERY_SOURCE
 
266
        TOKEN_ADJUST_PRIVILEGES
 
267
        TOKEN_ADJUST_GROUPS
 
268
        TOKEN_ADJUST_DEFAULT
 
269
 
 
270
        TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
 
271
                TOKEN_ASSIGN_PRIMARY |
 
272
                TOKEN_DUPLICATE |
 
273
                TOKEN_IMPERSONATE |
 
274
                TOKEN_QUERY |
 
275
                TOKEN_QUERY_SOURCE |
 
276
                TOKEN_ADJUST_PRIVILEGES |
 
277
                TOKEN_ADJUST_GROUPS |
 
278
                TOKEN_ADJUST_DEFAULT
 
279
        TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
 
280
        TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
 
281
                TOKEN_ADJUST_PRIVILEGES |
 
282
                TOKEN_ADJUST_GROUPS |
 
283
                TOKEN_ADJUST_DEFAULT
 
284
        TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
 
285
)
 
286
 
 
287
const (
 
288
        // do not reorder
 
289
        TokenUser = 1 + iota
 
290
        TokenGroups
 
291
        TokenPrivileges
 
292
        TokenOwner
 
293
        TokenPrimaryGroup
 
294
        TokenDefaultDacl
 
295
        TokenSource
 
296
        TokenType
 
297
        TokenImpersonationLevel
 
298
        TokenStatistics
 
299
        TokenRestrictedSids
 
300
        TokenSessionId
 
301
        TokenGroupsAndPrivileges
 
302
        TokenSessionReference
 
303
        TokenSandBoxInert
 
304
        TokenAuditPolicy
 
305
        TokenOrigin
 
306
        TokenElevationType
 
307
        TokenLinkedToken
 
308
        TokenElevation
 
309
        TokenHasRestrictions
 
310
        TokenAccessInformation
 
311
        TokenVirtualizationAllowed
 
312
        TokenVirtualizationEnabled
 
313
        TokenIntegrityLevel
 
314
        TokenUIAccess
 
315
        TokenMandatoryPolicy
 
316
        TokenLogonSid
 
317
        MaxTokenInfoClass
 
318
)
 
319
 
 
320
type SIDAndAttributes struct {
 
321
        Sid        *SID
 
322
        Attributes uint32
 
323
}
 
324
 
 
325
type Tokenuser struct {
 
326
        User SIDAndAttributes
 
327
}
 
328
 
 
329
type Tokenprimarygroup struct {
 
330
        PrimaryGroup *SID
 
331
}
 
332
 
 
333
type Tokengroups struct {
 
334
        GroupCount uint32
 
335
        Groups     [1]SIDAndAttributes
 
336
}
 
337
 
 
338
//sys   OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
 
339
//sys   GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
 
340
//sys   GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
 
341
 
 
342
// An access token contains the security information for a logon session.
 
343
// The system creates an access token when a user logs on, and every
 
344
// process executed on behalf of the user has a copy of the token.
 
345
// The token identifies the user, the user's groups, and the user's
 
346
// privileges. The system uses the token to control access to securable
 
347
// objects and to control the ability of the user to perform various
 
348
// system-related operations on the local computer.
 
349
type Token Handle
 
350
 
 
351
// OpenCurrentProcessToken opens the access token
 
352
// associated with current process.
 
353
func OpenCurrentProcessToken() (Token, error) {
 
354
        p, e := GetCurrentProcess()
 
355
        if e != nil {
 
356
                return 0, e
 
357
        }
 
358
        var t Token
 
359
        e = OpenProcessToken(p, TOKEN_QUERY, &t)
 
360
        if e != nil {
 
361
                return 0, e
 
362
        }
 
363
        return t, nil
 
364
}
 
365
 
 
366
// Close releases access to access token.
 
367
func (t Token) Close() error {
 
368
        return CloseHandle(Handle(t))
 
369
}
 
370
 
 
371
// getInfo retrieves a specified type of information about an access token.
 
372
func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
 
373
        n := uint32(initSize)
 
374
        for {
 
375
                b := make([]byte, n)
 
376
                e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
 
377
                if e == nil {
 
378
                        return unsafe.Pointer(&b[0]), nil
 
379
                }
 
380
                if e != ERROR_INSUFFICIENT_BUFFER {
 
381
                        return nil, e
 
382
                }
 
383
                if n <= uint32(len(b)) {
 
384
                        return nil, e
 
385
                }
 
386
        }
 
387
}
 
388
 
 
389
// GetTokenUser retrieves access token t user account information.
 
390
func (t Token) GetTokenUser() (*Tokenuser, error) {
 
391
        i, e := t.getInfo(TokenUser, 50)
 
392
        if e != nil {
 
393
                return nil, e
 
394
        }
 
395
        return (*Tokenuser)(i), nil
 
396
}
 
397
 
 
398
// GetTokenGroups retrieves group accounts associated with access token t.
 
399
func (t Token) GetTokenGroups() (*Tokengroups, error) {
 
400
        i, e := t.getInfo(TokenGroups, 50)
 
401
        if e != nil {
 
402
                return nil, e
 
403
        }
 
404
        return (*Tokengroups)(i), nil
 
405
}
 
406
 
 
407
// GetTokenPrimaryGroup retrieves access token t primary group information.
 
408
// A pointer to a SID structure representing a group that will become
 
409
// the primary group of any objects created by a process using this access token.
 
410
func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
 
411
        i, e := t.getInfo(TokenPrimaryGroup, 50)
 
412
        if e != nil {
 
413
                return nil, e
 
414
        }
 
415
        return (*Tokenprimarygroup)(i), nil
 
416
}
 
417
 
 
418
// GetUserProfileDirectory retrieves path to the
 
419
// root directory of the access token t user's profile.
 
420
func (t Token) GetUserProfileDirectory() (string, error) {
 
421
        n := uint32(100)
 
422
        for {
 
423
                b := make([]uint16, n)
 
424
                e := GetUserProfileDirectory(t, &b[0], &n)
 
425
                if e == nil {
 
426
                        return UTF16ToString(b), nil
 
427
                }
 
428
                if e != ERROR_INSUFFICIENT_BUFFER {
 
429
                        return "", e
 
430
                }
 
431
                if n <= uint32(len(b)) {
 
432
                        return "", e
 
433
                }
 
434
        }
 
435
}