• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2001
3  *
4  * This program is free software;  you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  * the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program;  if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * DESCRIPTION
20  *   check rmdir() fails with EPERM or EACCES
21  *
22  *	1. Create a directory tstdir1 and set the sticky bit, then
23  *         create directory tstdir2 under tstdir1. Call rmdir(),
24  *         set to be user nobody. Pass tstdir2 to rmdir(2), verify
25  *         the return value is not 0 and the errno is EPERM or EACCES.
26  *
27  *	2. Create a directory tstdir1 and doesn't give execute/search
28  *         permission to nobody, then create directory tstdir2 under
29  *         tstdir1. Call rmdir(), set to be user nobody. Pass
30  *         tstdir2 to rmdir(2), verify the return value is not 0 and
31  *         the errno is EACCES.
32  */
33 #include <errno.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <pwd.h>
37 #include <unistd.h>
38 #include "tst_test.h"
39 
40 #define DIR_MODE    0777
41 #define NOEXCUTE_MODE 0766
42 #define TESTDIR     "testdir"
43 #define TESTDIR2    "testdir/testdir2"
44 #define TESTDIR3    "testdir3"
45 #define TESTDIR4    "testdir3/testdir4"
46 
47 static struct testcase {
48 	mode_t dir_mode;
49 	char *subdir;
50 } tcases[] =  {
51 	{DIR_MODE | S_ISVTX, TESTDIR2},
52 	{NOEXCUTE_MODE, TESTDIR4},
53 };
54 
do_rmdir(unsigned int n)55 static void do_rmdir(unsigned int n)
56 {
57 	struct testcase *tc = &tcases[n];
58 
59 	TEST(rmdir(tc->subdir));
60 	if (TST_RET != -1) {
61 		tst_res(TFAIL, "rmdir() succeeded unexpectedly");
62 		return;
63 	}
64 
65 	if (TST_ERR != EACCES) {
66 		if (tc->dir_mode & S_ISVTX && TST_ERR == EPERM)
67 			tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
68 		else
69 			tst_res(TFAIL | TTERRNO, "expected EPERM, but got");
70 		return;
71 	}
72 
73 	tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
74 }
75 
76 
setup(void)77 static void setup(void)
78 {
79 	struct passwd *pw;
80 	pw = SAFE_GETPWNAM("nobody");
81 
82 	umask(0);
83 
84 	SAFE_MKDIR(TESTDIR, DIR_MODE | S_ISVTX);
85 	SAFE_MKDIR(TESTDIR2, DIR_MODE);
86 	SAFE_MKDIR(TESTDIR3, NOEXCUTE_MODE);
87 	SAFE_MKDIR(TESTDIR4, DIR_MODE);
88 
89 	SAFE_SETEUID(pw->pw_uid);
90 }
91 
cleanup(void)92 static void cleanup(void)
93 {
94 	SAFE_SETEUID(0);
95 }
96 
97 static struct tst_test test = {
98 	.setup = setup,
99 	.cleanup = cleanup,
100 	.tcnt = ARRAY_SIZE(tcases),
101 	.test = do_rmdir,
102 	.needs_root = 1,
103 	.needs_tmpdir = 1,
104 };
105 
106