source: branches/libc-0.6/src/libctests/glibc/posix/tst-chmod.c

Last change on this file was 2135, checked in by bird, 20 years ago

libc adjustments / config.

  • Property cvs2svn:cvs-rev set to 1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1/* Test for chmod functions.
2 Copyright (C) 2000, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21#include <dirent.h>
22#include <errno.h>
23#include <error.h>
24#include <fcntl.h>
25#include <mcheck.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include <sys/stat.h>
31
32#ifndef HAVE_64BIT_FILEIO_TYPES
33#define stat64 stat
34#define fstat64 fstat
35#endif
36
37
38#define OUT_OF_MEMORY \
39 do { \
40 puts ("cannot allocate memory"); \
41 result = 1; \
42 goto fail; \
43 } while (0)
44
45static int
46do_test (int argc, char *argv[])
47{
48 const char *builddir;
49 struct stat64 st1;
50 struct stat64 st2;
51 char *buf;
52 char *testdir;
53 char *testfile = NULL;
54 char *startdir;
55 size_t buflen;
56 int fd;
57 int result = 0;
58 DIR *dir;
59
60 mtrace ();
61
62 if (argc <= 1)
63 error (EXIT_FAILURE, 0, "no parameters");
64
65 /* This is where we will create the test files. */
66 builddir = argv[1];
67 buflen = strlen (builddir) + 50;
68
69 startdir = getcwd (NULL, 0);
70 if (startdir == NULL)
71 {
72 printf ("cannot get current directory: %m\n");
73 exit (EXIT_FAILURE);
74 }
75
76 /* A buffer large enough for everything we need. */
77 buf = (char *) alloca (buflen);
78
79 /* Create the directory name. */
80 snprintf (buf, buflen, "%s/chmoddirXXXXXX", builddir);
81
82 if (mkdtemp (buf) == NULL)
83 {
84 printf ("cannot create test directory: %m\n");
85 exit (EXIT_FAILURE);
86 }
87
88 if (chmod ("", 0600) == 0)
89 {
90 puts ("chmod(\"\", 0600 didn't fail");
91 result = 1;
92 }
93 else if (errno != ENOENT)
94 {
95 puts ("chmod(\"\",0600) does not set errno to ENOENT");
96 result = 1;
97 }
98
99 /* Create a duplicate. */
100 testdir = strdup (buf);
101 if (testdir == NULL)
102 OUT_OF_MEMORY;
103
104 if (stat64 (testdir, &st1) != 0)
105 {
106 printf ("cannot stat test directory: %m\n");
107 exit (1);
108 }
109 if (!S_ISDIR (st1.st_mode))
110 {
111 printf ("file not created as directory: %m\n");
112 exit (1);
113 }
114
115 /* We have to wait for a second to make sure the ctime changes. */
116 sleep (1);
117
118 /* Remove all access rights from the directory. */
119 if (chmod (testdir, 0) != 0)
120 {
121 printf ("cannot change mode of test directory: %m\n");
122 result = 1;
123 goto fail;
124 }
125
126 if (stat64 (testdir, &st2) != 0)
127 {
128 printf ("cannot stat test directory: %m\n");
129 result = 1;
130 goto fail;
131 }
132
133 /* Compare result. */
134 if ((st2.st_mode & ALLPERMS) != 0)
135 {
136 printf ("chmod(...,0) on directory left bits nonzero: %o\n",
137 st2.st_mode & ALLPERMS);
138 result = 1;
139 }
140 if (st1.st_ctime >= st2.st_ctime)
141 {
142 puts ("chmod(...,0) did not set ctime correctly");
143 result = 1;
144 }
145
146 /* Name of a file in the directory. */
147 snprintf (buf, buflen, "%s/file", testdir);
148 testfile = strdup (buf);
149 if (testfile == NULL)
150 OUT_OF_MEMORY;
151
152 fd = creat (testfile, 0);
153 if (fd != -1)
154 {
155 if (getuid () != 0)
156 {
157 puts ("managed to create test file in protected directory");
158 result = 1;
159 }
160 close (fd);
161 }
162 else if (errno != EACCES)
163 {
164 puts ("creat didn't generate correct errno value");
165 result = 1;
166 }
167
168 /* With this mode it still shouldn't be possible to create a file. */
169 if (chmod (testdir, 0600) != 0)
170 {
171 printf ("cannot change mode of test directory to 0600: %m\n");
172 result = 1;
173 goto fail;
174 }
175
176 fd = creat (testfile, 0);
177 if (fd != -1)
178 {
179 if (getuid () != 0)
180 {
181 puts ("managed to create test file in no-x protected directory");
182 result = 1;
183 }
184 close (fd);
185 }
186 else if (errno != EACCES)
187 {
188 puts ("creat didn't generate correct errno value");
189 result = 1;
190 }
191
192 /* Change the directory mode back to allow creating a file. This
193 time with fchmod. */
194 dir = opendir (testdir);
195 if (dir != NULL)
196 {
197 if (fchmod (dirfd (dir), 0700) != 0)
198 {
199 printf ("cannot change mode of test directory to 0700: %m\n");
200 result = 1;
201 closedir (dir);
202 goto fail;
203 }
204
205 closedir (dir);
206 }
207 else
208 {
209 printf ("cannot open directory: %m\n");
210 result = 1;
211
212 if (chmod (testdir, 0700) != 0)
213 {
214 printf ("cannot change mode of test directory to 0700: %m\n");
215 goto fail;
216 }
217 }
218
219 fd = creat (testfile, 0);
220 if (fd == -1)
221 {
222 puts ("still didn't manage to create test file in protected directory");
223 result = 1;
224 goto fail;
225 }
226 if (fstat64 (fd, &st1) != 0)
227 {
228 printf ("cannot stat new file: %m\n");
229 result = 1;
230 }
231 else if ((st1.st_mode & ALLPERMS) != 0)
232 {
233 puts ("file not created with access mode 0");
234 result = 1;
235 }
236 close (fd);
237
238 snprintf (buf, buflen, "%s/..", testdir);
239 chdir (buf);
240 /* We are now in the directory above the one we create the test
241 directory in. */
242
243 sleep (1);
244 snprintf (buf, buflen, "./%s/../%s/file",
245 basename (testdir), basename (testdir));
246 if (chmod (buf, 0600) != 0)
247 {
248 printf ("cannot change mode of file to 0600: %m\n");
249 result = 1;
250 goto fail;
251 }
252 snprintf (buf, buflen, "./%s//file", basename (testdir));
253 if (stat64 (buf, &st2) != 0)
254 {
255 printf ("cannot stat new file: %m\n");
256 result = 1;
257 }
258 else if ((st2.st_mode & ALLPERMS) != 0600)
259 {
260 puts ("file mode not changed to 0600");
261 result = 1;
262 }
263 else if (st1.st_ctime >= st2.st_ctime)
264 {
265 puts ("chmod(\".../file\",0600) did not set ctime correctly");
266 result = 1;
267 }
268
269 if (chmod (buf, 0777 | S_ISUID | S_ISGID) != 0)
270 {
271 printf ("cannot change mode of file to %o: %m\n",
272 0777 | S_ISUID | S_ISGID);
273 result = 1;
274 }
275 if (stat64 (buf, &st2) != 0)
276 {
277 printf ("cannot stat test file: %m\n");
278 result = 1;
279 }
280 else if ((st2.st_mode & ALLPERMS) != (0777 | S_ISUID | S_ISGID))
281 {
282 puts ("file mode not changed to 0777 | S_ISUID | S_ISGID");
283 result = 1;
284 }
285
286 if (chmod (basename (testdir), 0777 | S_ISUID | S_ISGID | S_ISVTX) != 0)
287 {
288 printf ("cannot change mode of test directory to %o: %m\n",
289 0777 | S_ISUID | S_ISGID | S_ISVTX);
290 result = 1;
291 }
292 if (stat64 (basename (testdir), &st2) != 0)
293 {
294 printf ("cannot stat test directory: %m\n");
295 result = 1;
296 }
297 else if ((st2.st_mode & ALLPERMS) != (0777 | S_ISUID | S_ISGID | S_ISVTX))
298 {
299 puts ("directory mode not changed to 0777 | S_ISUID | S_ISGID | S_ISGID");
300 result = 1;
301 }
302
303 snprintf (buf, buflen, "./%s/no-such-file", basename (testdir));
304 if (chmod (buf, 0600) != -1)
305 {
306 puts ("chmod(\".../no-such-file\",0600) did not fail");
307 result = 1;
308 }
309 else if (errno != ENOENT)
310 {
311 puts ("chmod(\".../no-such-file\",0600) does not set errno to ENOENT");
312 result = 1;
313 }
314
315 snprintf (buf, buflen, "%s/", basename (testdir));
316 if (chmod (basename (testdir), 0677) != 0)
317 {
318 printf ("cannot change mode of test directory to 0677: %m\n");
319 result = 1;
320 }
321 else
322 {
323 snprintf (buf, buflen, "./%s/file", basename (testdir));
324 if (chmod (buf, 0600) == 0)
325 {
326 if (getuid () != 0)
327 {
328 puts ("chmod(\".../file\") with no-exec directory succeeded");
329 result = 1;
330 }
331 }
332 else if (errno != EACCES)
333 {
334 puts ("chmod(\".../file\") with no-exec directory didn't set EACCES");
335 result = 1;
336 }
337 }
338
339 if (chmod (basename (testdir), 0777) != 0)
340 {
341 printf ("cannot change mode of test directory to 0777: %m\n");
342 result = 1;
343 goto fail;
344 }
345
346 snprintf (buf, buflen, "%s/file/cannot-be", basename (testdir));
347 if (chmod (buf, 0600) == 0)
348 {
349 puts ("chmod(\".../file/cannot-be\",0600) did not fail");
350 result = 1;
351 }
352 else if (errno != ENOTDIR)
353 {
354 puts ("chmod(\".../file/cannot-be\",0600) does not set errno to ENOTDIR");
355 result = 1;
356 }
357
358 fail:
359 chdir (startdir);
360
361 /* Remove all the files. */
362 chmod (testdir, 0700);
363 if (testfile != NULL)
364 {
365 chmod (testfile, 0700);
366 unlink (testfile);
367 }
368 rmdir (testdir);
369
370 /* Free the resources. */
371 free (testfile);
372 free (testdir);
373 free (startdir);
374
375 return result;
376}
377
378
379/* We need a few seconds since we have a few sleeps in the code. */
380#define TIMEOUT 20
381
382
383#include "../test-skeleton.c"
Note: See TracBrowser for help on using the repository browser.