Newer
Older
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package user
import (
"fmt"
"syscall"
"unsafe"
)
func lookupFullName(domain, username, domainAndUser string) (string, error) {
// try domain controller first
name, e := syscall.TranslateAccountName(domainAndUser,
syscall.NameSamCompatible, syscall.NameDisplay, 50)
if e != nil {
// domain lookup failed, perhaps this pc is not part of domain
d, e := syscall.UTF16PtrFromString(domain)
if e != nil {
return "", e
}
u, e := syscall.UTF16PtrFromString(username)
if e != nil {
return "", e
}
e = syscall.NetUserGetInfo(d, u, 10, &p)
// path executed when a domain user is disconnected from the domain
// pretend username is fullname
return username, nil
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
}
defer syscall.NetApiBufferFree(p)
i := (*syscall.UserInfo10)(unsafe.Pointer(p))
if i.FullName == nil {
return "", nil
}
name = syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:])
}
return name, nil
}
func newUser(usid *syscall.SID, gid, dir string) (*User, error) {
username, domain, t, e := usid.LookupAccount("")
if e != nil {
return nil, e
}
if t != syscall.SidTypeUser {
return nil, fmt.Errorf("user: should be user account type, not %d", t)
}
domainAndUser := domain + `\` + username
uid, e := usid.String()
if e != nil {
return nil, e
}
name, e := lookupFullName(domain, username, domainAndUser)
if e != nil {
return nil, e
}
u := &User{
Uid: uid,
Gid: gid,
Username: domainAndUser,
Name: name,
HomeDir: dir,
}
return u, nil
}
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
t, e := syscall.OpenCurrentProcessToken()
if e != nil {
return nil, e
}
u, e := t.GetTokenUser()
if e != nil {
return nil, e
}
pg, e := t.GetTokenPrimaryGroup()
if e != nil {
return nil, e
}
gid, e := pg.PrimaryGroup.String()
if e != nil {
return nil, e
}
dir, e := t.GetUserProfileDirectory()
if e != nil {
return nil, e
}
return newUser(u.User.Sid, gid, dir)
}
// BUG(brainman): Lookup and LookupId functions do not set
// Gid and HomeDir fields in the User struct returned on windows.
func newUserFromSid(usid *syscall.SID) (*User, error) {
// TODO(brainman): do not know where to get gid and dir fields
gid := "unknown"
dir := "Unknown directory"
return newUser(usid, gid, dir)
}
func lookup(username string) (*User, error) {
sid, _, t, e := syscall.LookupSID("", username)
if e != nil {
return nil, e
}
if t != syscall.SidTypeUser {
return nil, fmt.Errorf("user: should be user account type, not %d", t)
}
return newUserFromSid(sid)
}
func lookupId(uid string) (*User, error) {
sid, e := syscall.StringToSid(uid)
if e != nil {
return nil, e
}
return newUserFromSid(sid)
}