This source file includes following definitions.
- test_chown
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include "nap.h"
20
21 #if !HAVE_GETEGID
22 # define getegid() ((gid_t) -1)
23 #endif
24
25
26
27
28
29
30
31 static int
32 test_chown (int (*func) (char const *, uid_t, gid_t), bool print)
33 {
34 struct stat st1;
35 struct stat st2;
36 gid_t *gids = NULL;
37 int gids_count;
38 int result;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 ASSERT (mkdir (BASE "dir", 0700) == 0);
58 ASSERT (stat (BASE "dir", &st1) == 0);
59
60
61 result = func (BASE "dir", st1.st_uid, getegid ());
62 if (result == -1 && (errno == ENOSYS || errno == EPERM))
63 {
64 ASSERT (rmdir (BASE "dir") == 0);
65 if (print)
66 fputs ("skipping test: no support for ownership\n", stderr);
67 return 77;
68 }
69 ASSERT (result == 0);
70
71 ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
72 ASSERT (stat (BASE "dir/file", &st1) == 0);
73 ASSERT (st1.st_uid != (uid_t) -1);
74 ASSERT (st1.st_gid != (gid_t) -1);
75 ASSERT (st1.st_gid == getegid ());
76
77
78 errno = 0;
79 ASSERT (func ("", -1, -1) == -1);
80 ASSERT (errno == ENOENT);
81 errno = 0;
82 ASSERT (func ("no_such", -1, -1) == -1);
83 ASSERT (errno == ENOENT);
84 errno = 0;
85 ASSERT (func ("no_such/", -1, -1) == -1);
86 ASSERT (errno == ENOENT);
87 errno = 0;
88 ASSERT (func (BASE "dir/file/", -1, -1) == -1);
89 ASSERT (errno == ENOTDIR);
90
91
92 ASSERT (func (BASE "dir/file", -1, st1.st_gid) == 0);
93 ASSERT (func (BASE "dir/file", st1.st_uid, -1) == 0);
94 ASSERT (func (BASE "dir/file", (uid_t) -1, (gid_t) -1) == 0);
95 ASSERT (stat (BASE "dir/file", &st2) == 0);
96 ASSERT (st1.st_uid == st2.st_uid);
97 ASSERT (st1.st_gid == st2.st_gid);
98
99
100
101 nap ();
102 ASSERT (func (BASE "dir/file", st1.st_uid, st1.st_gid) == 0);
103 ASSERT (stat (BASE "dir/file", &st2) == 0);
104 ASSERT (st1.st_ctime < st2.st_ctime
105 || (st1.st_ctime == st2.st_ctime
106 && get_stat_ctime_ns (&st1) < get_stat_ctime_ns (&st2)));
107
108
109 if (symlink ("link", BASE "dir/link2"))
110 {
111 ASSERT (unlink (BASE "dir/file") == 0);
112 ASSERT (rmdir (BASE "dir") == 0);
113 if (print)
114 fputs ("skipping test: symlinks not supported on this file system\n",
115 stderr);
116 return 77;
117 }
118 errno = 0;
119 ASSERT (func (BASE "dir/link2", -1, -1) == -1);
120 ASSERT (errno == ENOENT);
121 errno = 0;
122 ASSERT (func (BASE "dir/link2/", st1.st_uid, st1.st_gid) == -1);
123 ASSERT (errno == ENOENT);
124 ASSERT (symlink ("file", BASE "dir/link") == 0);
125
126
127
128
129
130
131 gids_count = mgetgroups (NULL, st1.st_gid, &gids);
132 if (1 < gids_count)
133 {
134 ASSERT (gids[1] != st1.st_gid);
135 ASSERT (gids[1] != (gid_t) -1);
136 ASSERT (lstat (BASE "dir/link", &st2) == 0);
137 ASSERT (st1.st_uid == st2.st_uid);
138 ASSERT (st1.st_gid == st2.st_gid);
139 ASSERT (lstat (BASE "dir/link2", &st2) == 0);
140 ASSERT (st1.st_uid == st2.st_uid);
141 ASSERT (st1.st_gid == st2.st_gid);
142
143 errno = 0;
144 ASSERT (func (BASE "dir/link2/", -1, gids[1]) == -1);
145 ASSERT (errno == ENOTDIR);
146 ASSERT (stat (BASE "dir/file", &st2) == 0);
147 ASSERT (st1.st_uid == st2.st_uid);
148 ASSERT (st1.st_gid == st2.st_gid);
149 ASSERT (lstat (BASE "dir/link", &st2) == 0);
150 ASSERT (st1.st_uid == st2.st_uid);
151 ASSERT (st1.st_gid == st2.st_gid);
152 ASSERT (lstat (BASE "dir/link2", &st2) == 0);
153 ASSERT (st1.st_uid == st2.st_uid);
154 ASSERT (st1.st_gid == st2.st_gid);
155
156 ASSERT (func (BASE "dir/link2", -1, gids[1]) == 0);
157 ASSERT (stat (BASE "dir/file", &st2) == 0);
158 ASSERT (st1.st_uid == st2.st_uid);
159 ASSERT (gids[1] == st2.st_gid);
160 ASSERT (lstat (BASE "dir/link", &st2) == 0);
161 ASSERT (st1.st_uid == st2.st_uid);
162 ASSERT (st1.st_gid == st2.st_gid);
163 ASSERT (lstat (BASE "dir/link2", &st2) == 0);
164 ASSERT (st1.st_uid == st2.st_uid);
165 ASSERT (st1.st_gid == st2.st_gid);
166 }
167 else
168 {
169 struct stat l1;
170 struct stat l2;
171 ASSERT (stat (BASE "dir/file", &st1) == 0);
172 ASSERT (lstat (BASE "dir/link", &l1) == 0);
173 ASSERT (lstat (BASE "dir/link2", &l2) == 0);
174
175 nap ();
176 errno = 0;
177 ASSERT (func (BASE "dir/link2/", -1, st1.st_gid) == -1);
178 ASSERT (errno == ENOTDIR);
179 ASSERT (stat (BASE "dir/file", &st2) == 0);
180 ASSERT (st1.st_ctime == st2.st_ctime);
181 ASSERT (get_stat_ctime_ns (&st1) == get_stat_ctime_ns (&st2));
182 ASSERT (lstat (BASE "dir/link", &st2) == 0);
183 ASSERT (l1.st_ctime == st2.st_ctime);
184 ASSERT (get_stat_ctime_ns (&l1) == get_stat_ctime_ns (&st2));
185 ASSERT (lstat (BASE "dir/link2", &st2) == 0);
186 ASSERT (l2.st_ctime == st2.st_ctime);
187 ASSERT (get_stat_ctime_ns (&l2) == get_stat_ctime_ns (&st2));
188
189 ASSERT (func (BASE "dir/link2", -1, st1.st_gid) == 0);
190 ASSERT (stat (BASE "dir/file", &st2) == 0);
191 ASSERT (st1.st_ctime < st2.st_ctime
192 || (st1.st_ctime == st2.st_ctime
193 && get_stat_ctime_ns (&st1) < get_stat_ctime_ns (&st2)));
194 ASSERT (lstat (BASE "dir/link", &st2) == 0);
195 ASSERT (l1.st_ctime == st2.st_ctime);
196 ASSERT (get_stat_ctime_ns (&l1) == get_stat_ctime_ns (&st2));
197 ASSERT (lstat (BASE "dir/link2", &st2) == 0);
198 ASSERT (l2.st_ctime == st2.st_ctime);
199 ASSERT (get_stat_ctime_ns (&l2) == get_stat_ctime_ns (&st2));
200 }
201
202
203 free (gids);
204 ASSERT (unlink (BASE "dir/file") == 0);
205 ASSERT (unlink (BASE "dir/link") == 0);
206 ASSERT (unlink (BASE "dir/link2") == 0);
207 ASSERT (rmdir (BASE "dir") == 0);
208 return 0;
209 }