github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/os/user/lookup_windows.go (about) 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 user 6 7 import ( 8 "errors" 9 "fmt" 10 "syscall" 11 "unsafe" 12 ) 13 14 func init() { 15 groupImplemented = false 16 } 17 18 func isDomainJoined() (bool, error) { 19 var domain *uint16 20 var status uint32 21 err := syscall.NetGetJoinInformation(nil, &domain, &status) 22 if err != nil { 23 return false, err 24 } 25 syscall.NetApiBufferFree((*byte)(unsafe.Pointer(domain))) 26 return status == syscall.NetSetupDomainName, nil 27 } 28 29 func lookupFullNameDomain(domainAndUser string) (string, error) { 30 return syscall.TranslateAccountName(domainAndUser, 31 syscall.NameSamCompatible, syscall.NameDisplay, 50) 32 } 33 34 func lookupFullNameServer(servername, username string) (string, error) { 35 s, e := syscall.UTF16PtrFromString(servername) 36 if e != nil { 37 return "", e 38 } 39 u, e := syscall.UTF16PtrFromString(username) 40 if e != nil { 41 return "", e 42 } 43 var p *byte 44 e = syscall.NetUserGetInfo(s, u, 10, &p) 45 if e != nil { 46 return "", e 47 } 48 defer syscall.NetApiBufferFree(p) 49 i := (*syscall.UserInfo10)(unsafe.Pointer(p)) 50 if i.FullName == nil { 51 return "", nil 52 } 53 name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:]) 54 return name, nil 55 } 56 57 func lookupFullName(domain, username, domainAndUser string) (string, error) { 58 joined, err := isDomainJoined() 59 if err == nil && joined { 60 name, err := lookupFullNameDomain(domainAndUser) 61 if err == nil { 62 return name, nil 63 } 64 } 65 name, err := lookupFullNameServer(domain, username) 66 if err == nil { 67 return name, nil 68 } 69 // domain worked neither as a domain nor as a server 70 // could be domain server unavailable 71 // pretend username is fullname 72 return username, nil 73 } 74 75 func newUser(usid *syscall.SID, gid, dir string) (*User, error) { 76 username, domain, t, e := usid.LookupAccount("") 77 if e != nil { 78 return nil, e 79 } 80 if t != syscall.SidTypeUser { 81 return nil, fmt.Errorf("user: should be user account type, not %d", t) 82 } 83 domainAndUser := domain + `\` + username 84 uid, e := usid.String() 85 if e != nil { 86 return nil, e 87 } 88 name, e := lookupFullName(domain, username, domainAndUser) 89 if e != nil { 90 return nil, e 91 } 92 u := &User{ 93 Uid: uid, 94 Gid: gid, 95 Username: domainAndUser, 96 Name: name, 97 HomeDir: dir, 98 } 99 return u, nil 100 } 101 102 func current() (*User, error) { 103 t, e := syscall.OpenCurrentProcessToken() 104 if e != nil { 105 return nil, e 106 } 107 defer t.Close() 108 u, e := t.GetTokenUser() 109 if e != nil { 110 return nil, e 111 } 112 pg, e := t.GetTokenPrimaryGroup() 113 if e != nil { 114 return nil, e 115 } 116 gid, e := pg.PrimaryGroup.String() 117 if e != nil { 118 return nil, e 119 } 120 dir, e := t.GetUserProfileDirectory() 121 if e != nil { 122 return nil, e 123 } 124 return newUser(u.User.Sid, gid, dir) 125 } 126 127 // BUG(brainman): Lookup and LookupId functions do not set 128 // Gid and HomeDir fields in the User struct returned on windows. 129 130 func newUserFromSid(usid *syscall.SID) (*User, error) { 131 // TODO(brainman): do not know where to get gid and dir fields 132 gid := "unknown" 133 dir := "Unknown directory" 134 return newUser(usid, gid, dir) 135 } 136 137 func lookupUser(username string) (*User, error) { 138 sid, _, t, e := syscall.LookupSID("", username) 139 if e != nil { 140 return nil, e 141 } 142 if t != syscall.SidTypeUser { 143 return nil, fmt.Errorf("user: should be user account type, not %d", t) 144 } 145 return newUserFromSid(sid) 146 } 147 148 func lookupUserId(uid string) (*User, error) { 149 sid, e := syscall.StringToSid(uid) 150 if e != nil { 151 return nil, e 152 } 153 return newUserFromSid(sid) 154 } 155 156 func lookupGroup(groupname string) (*Group, error) { 157 return nil, errors.New("user: LookupGroup not implemented on windows") 158 } 159 160 func lookupGroupId(string) (*Group, error) { 161 return nil, errors.New("user: LookupGroupId not implemented on windows") 162 } 163 164 func listGroups(*User) ([]string, error) { 165 return nil, errors.New("user: GroupIds not implemented on windows") 166 }