Home | History | Annotate | Download | only in mkdir
      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 /*  DESCRIPTION
     19  *  This test will verify that new directory created by mkdir(2) inherites
     20  *  the group ID from the parent directory and S_ISGID bit, if the S_ISGID
     21  *  bit is set in the parent directory.
     22  */
     23 
     24 #include <errno.h>
     25 #include <sys/stat.h>
     26 #include <sys/types.h>
     27 #include <pwd.h>
     28 #include <sys/wait.h>
     29 #include <unistd.h>
     30 #include <stdlib.h>
     31 #include "tst_test.h"
     32 
     33 #define TESTDIR1	"testdir1"
     34 #define TESTDIR2	"testdir1/testdir2"
     35 
     36 static uid_t nobody_uid, bin_uid;
     37 static gid_t nobody_gid, bin_gid;
     38 
     39 static void verify_mkdir(void)
     40 {
     41 	struct stat buf1, buf2;
     42 	pid_t pid;
     43 	int fail = 0;
     44 
     45 	pid = SAFE_FORK();
     46 	if (pid == 0) {
     47 		SAFE_SETREGID(bin_gid, bin_gid);
     48 		SAFE_SETREUID(bin_uid, bin_uid);
     49 		SAFE_MKDIR(TESTDIR2, 0777);
     50 
     51 		SAFE_STAT(TESTDIR2, &buf2);
     52 		SAFE_STAT(TESTDIR1, &buf1);
     53 
     54 		if (buf2.st_gid != buf1.st_gid) {
     55 			tst_res(TFAIL,
     56 				"New dir FAILED to inherit GID have %d expected %d",
     57 				buf2.st_gid, buf1.st_gid);
     58 			fail = 1;
     59 		}
     60 
     61 		if (!(buf2.st_mode & S_ISGID)) {
     62 			tst_res(TFAIL, "New dir FAILED to inherit S_ISGID");
     63 			fail = 1;
     64 		}
     65 
     66 		if (!fail)
     67 			tst_res(TPASS, "New dir inherited GID and S_ISGID");
     68 
     69 		exit(0);
     70 	}
     71 
     72 	tst_reap_children();
     73 	SAFE_RMDIR(TESTDIR2);
     74 }
     75 
     76 
     77 static void setup(void)
     78 {
     79 	struct passwd *pw;
     80 	struct stat buf;
     81 	pid_t pid;
     82 
     83 	pw = SAFE_GETPWNAM("nobody");
     84 	nobody_uid = pw->pw_uid;
     85 	nobody_gid = pw->pw_gid;
     86 	pw = SAFE_GETPWNAM("bin");
     87 	bin_uid = pw->pw_uid;
     88 	bin_gid = pw->pw_gid;
     89 
     90 	umask(0);
     91 
     92 	pid = SAFE_FORK();
     93 	if (pid == 0) {
     94 		SAFE_SETREGID(nobody_gid, nobody_gid);
     95 		SAFE_SETREUID(nobody_uid, nobody_uid);
     96 		SAFE_MKDIR(TESTDIR1, 0777);
     97 		SAFE_STAT(TESTDIR1, &buf);
     98 		SAFE_CHMOD(TESTDIR1, buf.st_mode | S_ISGID);
     99 		exit(0);
    100 	}
    101 
    102 	tst_reap_children();
    103 }
    104 
    105 static struct tst_test test = {
    106 	.setup = setup,
    107 	.needs_tmpdir = 1,
    108 	.needs_root = 1,
    109 	.test_all = verify_mkdir,
    110 	.forks_child = 1,
    111 };
    112