github.com/puellanivis/breton@v0.2.16/lib/os/user/lookup_windows.go (about) 1 // Code generated by Uses Names with Id instead of ID. DO NOT EDIT. 2 // The above line skips linter because we use functions with the name Id instead of ID, but the linter refuses to allow this. 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package user 8 9 import ( 10 "errors" 11 "fmt" 12 "syscall" 13 "unsafe" 14 ) 15 16 func init() { 17 groupImplemented = false 18 } 19 20 func isDomainJoined() (bool, error) { 21 var domain *uint16 22 var status uint32 23 err := syscall.NetGetJoinInformation(nil, &domain, &status) 24 if err != nil { 25 return false, err 26 } 27 syscall.NetApiBufferFree((*byte)(unsafe.Pointer(domain))) 28 return status == syscall.NetSetupDomainName, nil 29 } 30 31 func lookupFullNameDomain(domainAndUser string) (string, error) { 32 return syscall.TranslateAccountName(domainAndUser, 33 syscall.NameSamCompatible, syscall.NameDisplay, 50) 34 } 35 36 func lookupFullNameServer(servername, username string) (string, error) { 37 s, e := syscall.UTF16PtrFromString(servername) 38 if e != nil { 39 return "", e 40 } 41 u, e := syscall.UTF16PtrFromString(username) 42 if e != nil { 43 return "", e 44 } 45 var p *byte 46 e = syscall.NetUserGetInfo(s, u, 10, &p) 47 if e != nil { 48 return "", e 49 } 50 defer syscall.NetApiBufferFree(p) 51 i := (*syscall.UserInfo10)(unsafe.Pointer(p)) 52 if i.FullName == nil { 53 return "", nil 54 } 55 name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:]) 56 return name, nil 57 } 58 59 func lookupFullName(domain, username, domainAndUser string) (string, error) { 60 name, err := lookupFullNameServer(domain, username) 61 if err == nil { 62 return name, nil 63 } 64 65 joined, err := isDomainJoined() 66 if err == nil && joined { 67 name, err := lookupFullNameDomain(domainAndUser) 68 if err == nil { 69 return name, nil 70 } 71 } 72 73 // domain worked neither as a domain nor as a server 74 // could be domain server unavailable 75 // pretend username is fullname 76 return username, nil 77 } 78 79 func newUser(usid *syscall.SID, gid, dir string) (*User, error) { 80 username, domain, t, e := usid.LookupAccount("") 81 if e != nil { 82 return nil, e 83 } 84 if t != syscall.SidTypeUser { 85 return nil, fmt.Errorf("user: should be user account type, not %d", t) 86 } 87 domainAndUser := domain + `\` + username 88 uid, e := usid.String() 89 if e != nil { 90 return nil, e 91 } 92 name, e := lookupFullName(domain, username, domainAndUser) 93 if e != nil { 94 return nil, e 95 } 96 u := &User{ 97 Uid: uid, 98 Gid: gid, 99 Username: domainAndUser, 100 Name: name, 101 HomeDir: dir, 102 } 103 return u, nil 104 } 105 106 // CurrentUsername returns the username of the current user. 107 func CurrentUsername() (string, error) { 108 t, e := syscall.OpenCurrentProcessToken() 109 if e != nil { 110 return "", e 111 } 112 defer t.Close() 113 114 u, e := t.GetTokenUser() 115 if e != nil { 116 return "", e 117 } 118 119 username, domain, ut, e := u.User.Sid.LookupAccount("") 120 if e != nil { 121 return "", e 122 } 123 if ut != syscall.SidTypeUser { 124 return "", fmt.Errorf("user: should be user account type, not %d", t) 125 } 126 127 return domain + `\` + username, nil 128 } 129 130 // CurrentHomeDir returns the home directory of the current user. 131 func CurrentHomeDir() (string, error) { 132 t, e := syscall.OpenCurrentProcessToken() 133 if e != nil { 134 return "", e 135 } 136 defer t.Close() 137 138 return t.GetUserProfileDirectory() 139 } 140 141 func current() (*User, error) { 142 t, e := syscall.OpenCurrentProcessToken() 143 if e != nil { 144 return nil, e 145 } 146 defer t.Close() 147 u, e := t.GetTokenUser() 148 if e != nil { 149 return nil, e 150 } 151 pg, e := t.GetTokenPrimaryGroup() 152 if e != nil { 153 return nil, e 154 } 155 gid, e := pg.PrimaryGroup.String() 156 if e != nil { 157 return nil, e 158 } 159 dir, e := t.GetUserProfileDirectory() 160 if e != nil { 161 return nil, e 162 } 163 return newUser(u.User.Sid, gid, dir) 164 } 165 166 // BUG(brainman): Lookup and LookupId functions do not set 167 // Gid and HomeDir fields in the User struct returned on windows. 168 169 func newUserFromSid(usid *syscall.SID) (*User, error) { 170 // TODO(brainman): do not know where to get gid and dir fields 171 gid := "unknown" 172 dir := "Unknown directory" 173 return newUser(usid, gid, dir) 174 } 175 176 func lookupUser(username string) (*User, error) { 177 sid, _, t, e := syscall.LookupSID("", username) 178 if e != nil { 179 return nil, e 180 } 181 if t != syscall.SidTypeUser { 182 return nil, fmt.Errorf("user: should be user account type, not %d", t) 183 } 184 return newUserFromSid(sid) 185 } 186 187 func lookupUserId(uid string) (*User, error) { 188 sid, e := syscall.StringToSid(uid) 189 if e != nil { 190 return nil, e 191 } 192 return newUserFromSid(sid) 193 } 194 195 func lookupGroup(groupname string) (*Group, error) { 196 return nil, errors.New("user: LookupGroup not implemented on windows") 197 } 198 199 func lookupGroupId(string) (*Group, error) { 200 return nil, errors.New("user: LookupGroupId not implemented on windows") 201 } 202 203 func listGroups(*User) ([]string, error) { 204 return nil, errors.New("user: GroupIds not implemented on windows") 205 }