Source file
src/os/user/user_windows_test.go
1
2
3
4
5 package user
6
7 import (
8 "crypto/rand"
9 "encoding/base64"
10 "errors"
11 "fmt"
12 "internal/syscall/windows"
13 "internal/testenv"
14 "os"
15 "os/exec"
16 "runtime"
17 "strconv"
18 "syscall"
19 "testing"
20 "unsafe"
21 )
22
23
24
25
26 func windowsTestAcount(t *testing.T) (syscall.Token, *User) {
27 const testUserName = "GoStdTestUser01"
28 var password [33]byte
29 rand.Read(password[:])
30
31 pwd := base64.StdEncoding.EncodeToString(password[:]) + "_-As@!%*(1)4#2"
32 name, err := syscall.UTF16PtrFromString(testUserName)
33 if err != nil {
34 t.Fatal(err)
35 }
36 pwd16, err := syscall.UTF16PtrFromString(pwd)
37 if err != nil {
38 t.Fatal(err)
39 }
40 userInfo := windows.UserInfo1{
41 Name: name,
42 Password: pwd16,
43 Priv: windows.USER_PRIV_USER,
44 }
45
46 err = windows.NetUserAdd(nil, 1, (*byte)(unsafe.Pointer(&userInfo)), nil)
47 if errors.Is(err, syscall.ERROR_ACCESS_DENIED) {
48 t.Skip("skipping test; don't have permission to create user")
49 }
50 if errors.Is(err, windows.NERR_UserExists) {
51
52 if err = windows.NetUserDel(nil, name); err != nil {
53 t.Fatal(err)
54 }
55 if err = windows.NetUserAdd(nil, 1, (*byte)(unsafe.Pointer(&userInfo)), nil); err != nil {
56 t.Fatal(err)
57 }
58 } else if err != nil {
59 t.Fatal(err)
60 }
61 t.Cleanup(func() {
62 if err = windows.NetUserDel(nil, name); err != nil {
63 if !errors.Is(err, windows.NERR_UserNotFound) {
64 t.Fatal(err)
65 }
66 }
67 })
68 domain, err := syscall.UTF16PtrFromString(".")
69 if err != nil {
70 t.Fatal(err)
71 }
72 const LOGON32_PROVIDER_DEFAULT = 0
73 const LOGON32_LOGON_INTERACTIVE = 2
74 var token syscall.Token
75 if err = windows.LogonUser(name, domain, pwd16, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &token); err != nil {
76 t.Fatal(err)
77 }
78 t.Cleanup(func() {
79 token.Close()
80 })
81 usr, err := Lookup(testUserName)
82 if err != nil {
83 t.Fatal(err)
84 }
85 return token, usr
86 }
87
88 func TestImpersonatedSelf(t *testing.T) {
89 runtime.LockOSThread()
90 defer runtime.UnlockOSThread()
91
92 want, err := current()
93 if err != nil {
94 t.Fatal(err)
95 }
96
97 levels := []uint32{
98 windows.SecurityAnonymous,
99 windows.SecurityIdentification,
100 windows.SecurityImpersonation,
101 windows.SecurityDelegation,
102 }
103 for _, level := range levels {
104 t.Run(strconv.Itoa(int(level)), func(t *testing.T) {
105 if err = windows.ImpersonateSelf(level); err != nil {
106 t.Fatal(err)
107 }
108 defer windows.RevertToSelf()
109
110 got, err := current()
111 if level == windows.SecurityAnonymous {
112
113
114 if err == nil {
115 t.Fatal("expected error")
116 }
117 return
118 }
119 if err != nil {
120 t.Fatal(err)
121 }
122 compare(t, want, got)
123 })
124 }
125 }
126
127 func TestImpersonated(t *testing.T) {
128 runtime.LockOSThread()
129 defer runtime.UnlockOSThread()
130
131 want, err := current()
132 if err != nil {
133 t.Fatal(err)
134 }
135
136
137 token, _ := windowsTestAcount(t)
138
139
140 if err = windows.ImpersonateLoggedOnUser(token); err != nil {
141 t.Fatal(err)
142 }
143 defer func() {
144 err = windows.RevertToSelf()
145 if err != nil {
146
147 panic(err)
148 }
149 }()
150
151 got, err := current()
152 if err != nil {
153 t.Fatal(err)
154 }
155 compare(t, want, got)
156 }
157
158 func TestCurrentNetapi32(t *testing.T) {
159 if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
160
161
162 Current()
163
164
165 netapi32, err := syscall.UTF16PtrFromString("netapi32.dll")
166 if err != nil {
167 fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
168 os.Exit(9)
169 return
170 }
171 mod, _ := windows.GetModuleHandle(netapi32)
172 if mod != 0 {
173 fmt.Fprintf(os.Stderr, "netapi32.dll is loaded\n")
174 os.Exit(9)
175 return
176 }
177 os.Exit(0)
178 return
179 }
180 exe := testenv.Executable(t)
181 cmd := testenv.CleanCmdEnv(exec.Command(exe, "-test.run=^TestCurrentNetapi32$"))
182 cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1")
183 out, err := cmd.CombinedOutput()
184 if err != nil {
185 t.Fatalf("%v\n%s", err, out)
186 }
187 }
188
189 func TestGroupIdsTestUser(t *testing.T) {
190
191 _, user := windowsTestAcount(t)
192
193 gids, err := user.GroupIds()
194 if err != nil {
195 t.Fatal(err)
196 }
197
198 if err != nil {
199 t.Fatalf("%+v.GroupIds(): %v", user, err)
200 }
201 if !containsID(gids, user.Gid) {
202 t.Errorf("%+v.GroupIds() = %v; does not contain user GID %s", user, gids, user.Gid)
203 }
204 }
205
View as plain text