fchmod03.c revision 605fa3362fd7cef0baa2131be32cf44661783d3e
165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/*
265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Copyright (c) International Business Machines  Corp., 2001
465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   This program is free software;  you can redistribute it and/or modify
665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   it under the terms of the GNU General Public License as published by
765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   the Free Software Foundation; either version 2 of the License, or
865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   (at your option) any later version.
965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
1065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   This program is distributed in the hope that it will be useful,
1165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
1265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
1365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   the GNU General Public License for more details.
1465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
1565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   You should have received a copy of the GNU General Public License
1665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   along with this program;  if not, write to the Free Software
1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
1965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
2065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/*
2165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Test Name: fchmod03
2265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Test Description:
2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  Verify that, fchmod(2) will succeed to change the mode of a file
2565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  and set the sticky bit on it if invoked by non-root (uid != 0)
2665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  process with the following constraints,
2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	- the process is the owner of the file.
2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	- the effective group ID or one of the supplementary group ID's of the
2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	  process is equal to the group ID of the file.
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Expected Result:
3265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  fchmod() should return value 0 on success and succeeds to change
3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  the mode of specified file, sets sticky bit on it.
3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Algorithm:
36d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko *  Setup:
3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Setup signal handling.
3865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Create temporary directory.
3965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Pause for SIGUSR1 if option specified.
4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
4165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  Test:
4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Loop if the proper options are given.
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Execute system call
4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Check return code, if system call failed (return=-1)
4565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   	Log the errno and Issue a FAIL message.
46d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko *   Otherwise,
4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   	Verify the Functionality of system call
4865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *      if successful,
4965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *      	Issue Functionality-Pass message.
5065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *      Otherwise,
5165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *		Issue Functionality-Fail message.
5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  Cleanup:
5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Print errno log and/or timing stats if options given
5465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *   Delete the temporary directory created.
5565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
5665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Usage:  <for command-line>
5765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *  fchmod03 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *     where,  -c n : Run n copies concurrently.
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *             -f   : Turn off functionality Testing.
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	       -i n : Execute test n times.
6165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	       -I x : Execute test for x seconds.
6265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	       -P x : Pause for x seconds between iterations.
6365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	       -t   : Turn on syscall timing.
6465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
6565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * HISTORY
6665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *	07/2001 Ported by Wayne Boyer
6765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
68d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * RESTRICTIONS:
69d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko *  This test should be run by 'non-super-user' only.
7065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
7165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
7365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <stdio.h>
7465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <sys/types.h>
7565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <sys/stat.h>
7665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <sys/fcntl.h>
7765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <errno.h>
7865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <string.h>
7965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <signal.h>
8065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include <pwd.h>
8165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include "test.h"
8365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#include "usctest.h"
8465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#define FILE_MODE       (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
8665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#define PERMS		01777
8765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko#define TESTFILE	"testfile"
8865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
8965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoint fd;				/* file descriptor for test file */
9065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkochar *TCID = "fchmod03";
9165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoint TST_TOTAL = 1;
9265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
9365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkochar nobody_uid[] = "nobody";
9465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkostruct passwd *ltpuser;
9565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
9665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkovoid setup();			/* Main setup function for the test */
9765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkovoid cleanup();			/* Main cleanup function for the test */
9865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
9965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoint main(int ac, char **av)
10065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko{
10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	struct stat stat_buf;	/* stat struct. */
10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	int lc;
10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	const char *msg;
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	mode_t file_mode;	/* mode permissions set on testfile */
10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
10865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
10965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	setup();
11065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
11165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	for (lc = 0; TEST_LOOPING(lc); lc++) {
11265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
11365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_count = 0;
114d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
11565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		TEST(fchmod(fd, PERMS));
11665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
11765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		if (TEST_RETURN == -1) {
11865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko			tst_resm(TFAIL | TTERRNO, "fchmod failed");
11965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko			continue;
12065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		}
12165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		/*
12265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		 * Get the file information using
12365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		 * fstat(2).
12465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		 */
12565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		if (fstat(fd, &stat_buf) == -1)
12665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko			tst_brkm(TFAIL | TERRNO, cleanup,
12765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko				 "fstat failed");
12865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		file_mode = stat_buf.st_mode;
12965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
13065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		/* Verify STICKY BIT set on testfile */
13165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		if ((file_mode & PERMS) != PERMS)
13265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko			tst_resm(TFAIL, "%s: Incorrect modes 0%3o, "
13365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko				 "Expected 0777", TESTFILE, file_mode);
13465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		else
13565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko			tst_resm(TPASS, "Functionality of fchmod(%d, "
13665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko				 "%#o) successful", fd, PERMS);
13765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	}
13865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
13965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	cleanup();
14065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	tst_exit();
14165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
14265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
14365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkovoid setup(void)
14465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko{
14565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	tst_sig(NOFORK, DEF_HANDLER, cleanup);
14765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
14865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	tst_require_root(NULL);
14965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
15065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	ltpuser = getpwnam(nobody_uid);
15165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	if (ltpuser == NULL)
15265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_brkm(TBROK | TERRNO, NULL, "getpwnam failed");
15365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	if (seteuid(ltpuser->pw_uid) == -1)
15465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_brkm(TBROK | TERRNO, NULL, "seteuid failed");
15565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
15665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	TEST_PAUSE;
15765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
15865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	tst_tmpdir();
15965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
16065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	/*
16165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	 * Create a test file under temporary directory with specified
16265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	 * mode permissios and set the ownership of the test file to the
16365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	 * uid/gid of guest user.
16465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	 */
16565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	if ((fd = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1)
16665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_brkm(TBROK | TERRNO, cleanup, "open failed");
16765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
16865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
16965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkovoid cleanup(void)
17065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko{
17165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko	if (close(fd) == -1)
17265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko		tst_resm(TWARN | TERRNO, "close failed");
17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
174d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko	tst_rmdir();
175d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko