xref: /minix3/minix/tests/test11.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* test 11 */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc #include <sys/types.h>
4*433d6423SLionel Sambuc #include <sys/stat.h>
5*433d6423SLionel Sambuc #include <sys/wait.h>
6*433d6423SLionel Sambuc #include <errno.h>
7*433d6423SLionel Sambuc #include <fcntl.h>
8*433d6423SLionel Sambuc #include <stdlib.h>
9*433d6423SLionel Sambuc #include <string.h>
10*433d6423SLionel Sambuc #include <unistd.h>
11*433d6423SLionel Sambuc #include <stdio.h>
12*433d6423SLionel Sambuc 
13*433d6423SLionel Sambuc #define ITERATIONS 10
14*433d6423SLionel Sambuc int max_error = 1;
15*433d6423SLionel Sambuc #include "common.h"
16*433d6423SLionel Sambuc 
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc int errct, subtest;
19*433d6423SLionel Sambuc char *envp[3] = {"spring", "summer", 0};
20*433d6423SLionel Sambuc char *passwd_file = "/etc/passwd";
21*433d6423SLionel Sambuc 
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc int main(int argc, char *argv[]);
24*433d6423SLionel Sambuc void test11a(void);
25*433d6423SLionel Sambuc void test11b(void);
26*433d6423SLionel Sambuc void test11c(void);
27*433d6423SLionel Sambuc void test11d(void);
28*433d6423SLionel Sambuc 
main(argc,argv)29*433d6423SLionel Sambuc int main(argc, argv)
30*433d6423SLionel Sambuc int argc;
31*433d6423SLionel Sambuc char *argv[];
32*433d6423SLionel Sambuc {
33*433d6423SLionel Sambuc   int i, m = 0xFFFF;
34*433d6423SLionel Sambuc 
35*433d6423SLionel Sambuc   if (argc == 2) m = atoi(argv[1]);
36*433d6423SLionel Sambuc 
37*433d6423SLionel Sambuc   start(11);
38*433d6423SLionel Sambuc 
39*433d6423SLionel Sambuc   system("cp ../t11a .");
40*433d6423SLionel Sambuc   system("cp ../t11b .");
41*433d6423SLionel Sambuc 
42*433d6423SLionel Sambuc   if (geteuid() != 0) {
43*433d6423SLionel Sambuc 	printf("must be setuid root; test aborted\n");
44*433d6423SLionel Sambuc 	exit(1);
45*433d6423SLionel Sambuc   }
46*433d6423SLionel Sambuc   if (getuid() == 0) {
47*433d6423SLionel Sambuc        printf("must be setuid root logged in as someone else; test aborted\n");
48*433d6423SLionel Sambuc        exit(1);
49*433d6423SLionel Sambuc   }
50*433d6423SLionel Sambuc 
51*433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
52*433d6423SLionel Sambuc 	if (m & 0001) test11a();
53*433d6423SLionel Sambuc 	if (m & 0002) test11b();
54*433d6423SLionel Sambuc 	if (m & 0004) test11c();
55*433d6423SLionel Sambuc 	if (m & 0010) test11d();
56*433d6423SLionel Sambuc   }
57*433d6423SLionel Sambuc   quit();
58*433d6423SLionel Sambuc   return(-1);
59*433d6423SLionel Sambuc }
60*433d6423SLionel Sambuc 
test11a()61*433d6423SLionel Sambuc void test11a()
62*433d6423SLionel Sambuc {
63*433d6423SLionel Sambuc /* Test exec */
64*433d6423SLionel Sambuc   int n, fd;
65*433d6423SLionel Sambuc   char aa[4];
66*433d6423SLionel Sambuc 
67*433d6423SLionel Sambuc   subtest = 1;
68*433d6423SLionel Sambuc 
69*433d6423SLionel Sambuc   if (fork()) {
70*433d6423SLionel Sambuc 	wait(&n);
71*433d6423SLionel Sambuc 	if (n != 25600) e(1);
72*433d6423SLionel Sambuc 	unlink("t1");
73*433d6423SLionel Sambuc 	unlink("t2");
74*433d6423SLionel Sambuc   } else {
75*433d6423SLionel Sambuc 	if (chown("t11a", 10, 20) < 0) e(2);
76*433d6423SLionel Sambuc 	chmod("t11a", 0666);
77*433d6423SLionel Sambuc 
78*433d6423SLionel Sambuc 	/* The following call should fail because the mode has no X
79*433d6423SLionel Sambuc 	 * bits on. If a bug lets it unexpectedly succeed, the child
80*433d6423SLionel Sambuc 	 * will print an error message since the arguments are wrong.
81*433d6423SLionel Sambuc  	 */
82*433d6423SLionel Sambuc 	execl("t11a", "t11a", (char *) 0); /* should fail -- no X bits */
83*433d6423SLionel Sambuc 
84*433d6423SLionel Sambuc 	/* Control should come here after the failed execl(). */
85*433d6423SLionel Sambuc 	chmod("t11a", 06555);
86*433d6423SLionel Sambuc 	if ((fd = creat("t1", 0600)) != 3) e(3);
87*433d6423SLionel Sambuc 	if (close(fd) < 0) e(4);
88*433d6423SLionel Sambuc 	if (open("t1", O_RDWR) != 3) e(5);
89*433d6423SLionel Sambuc 	if (chown("t1", 10, 99) < 0) e(6);
90*433d6423SLionel Sambuc 	if ((fd = creat("t2", 0060)) != 4) e(7);
91*433d6423SLionel Sambuc 	if (close(fd) < 0) e(8);
92*433d6423SLionel Sambuc 	if (open("t2", O_RDWR) != 4) e(9);
93*433d6423SLionel Sambuc 	if (chown("t2", 99, 20) < 0) e(10);
94*433d6423SLionel Sambuc 	if (setgid(6) < 0) e(11);
95*433d6423SLionel Sambuc 	if (setuid(5) < 0) e(12);
96*433d6423SLionel Sambuc 	if (getuid() != 5) e(13);
97*433d6423SLionel Sambuc 	if (geteuid() != 5) e(14);
98*433d6423SLionel Sambuc 	if (getgid() != 6) e(15);
99*433d6423SLionel Sambuc 	if (getegid() != 6) e(16);
100*433d6423SLionel Sambuc 	aa[0] = 3;
101*433d6423SLionel Sambuc 	aa[1] = 5;
102*433d6423SLionel Sambuc 	aa[2] = 7;
103*433d6423SLionel Sambuc 	aa[3] = 9;
104*433d6423SLionel Sambuc 	if (write(3, aa, 4) != 4) e(17);
105*433d6423SLionel Sambuc 	lseek(3, 2L, 0);
106*433d6423SLionel Sambuc 	execle("t11a", "t11a", "arg0", "arg1", "arg2", (char *) 0, envp);
107*433d6423SLionel Sambuc 	e(18);
108*433d6423SLionel Sambuc 	printf("Can't exec t11a\n");
109*433d6423SLionel Sambuc 	exit(3);
110*433d6423SLionel Sambuc   }
111*433d6423SLionel Sambuc }
112*433d6423SLionel Sambuc 
test11b()113*433d6423SLionel Sambuc void test11b()
114*433d6423SLionel Sambuc {
115*433d6423SLionel Sambuc   int n;
116*433d6423SLionel Sambuc   char *argv[5];
117*433d6423SLionel Sambuc 
118*433d6423SLionel Sambuc   subtest = 2;
119*433d6423SLionel Sambuc   if (fork()) {
120*433d6423SLionel Sambuc 	wait(&n);
121*433d6423SLionel Sambuc 	if (n != (75 << 8)) e(20);
122*433d6423SLionel Sambuc   } else {
123*433d6423SLionel Sambuc 	/* Child tests execv. */
124*433d6423SLionel Sambuc 	argv[0] = "t11b";
125*433d6423SLionel Sambuc 	argv[1] = "abc";
126*433d6423SLionel Sambuc 	argv[2] = "defghi";
127*433d6423SLionel Sambuc 	argv[3] = "j";
128*433d6423SLionel Sambuc 	argv[4] = 0;
129*433d6423SLionel Sambuc 	execv("t11b", argv);
130*433d6423SLionel Sambuc 	e(19);
131*433d6423SLionel Sambuc   }
132*433d6423SLionel Sambuc }
133*433d6423SLionel Sambuc 
test11c()134*433d6423SLionel Sambuc void test11c()
135*433d6423SLionel Sambuc {
136*433d6423SLionel Sambuc /* Test getlogin().  This test  MUST run setuid root. */
137*433d6423SLionel Sambuc 
138*433d6423SLionel Sambuc   int n, etc_uid;
139*433d6423SLionel Sambuc   uid_t ruid, euid;
140*433d6423SLionel Sambuc   char *lnamep, *p;
141*433d6423SLionel Sambuc #define MAXLINELEN 200
142*433d6423SLionel Sambuc   char array[MAXLINELEN], save[L_cuserid];
143*433d6423SLionel Sambuc   FILE *stream;
144*433d6423SLionel Sambuc 
145*433d6423SLionel Sambuc   subtest = 3;
146*433d6423SLionel Sambuc   errno = -2000;		/* None of these calls set errno. */
147*433d6423SLionel Sambuc   save[0] = '#';
148*433d6423SLionel Sambuc   save[1] = '0';
149*433d6423SLionel Sambuc   ruid = getuid();
150*433d6423SLionel Sambuc   euid = geteuid();
151*433d6423SLionel Sambuc   lnamep = getlogin();
152*433d6423SLionel Sambuc   strcpy(save, lnamep);
153*433d6423SLionel Sambuc 
154*433d6423SLionel Sambuc   /* Because we are setuid, login != 'root' */
155*433d6423SLionel Sambuc   if (euid != 0) e(1);
156*433d6423SLionel Sambuc   if (ruid == 0) e(2);
157*433d6423SLionel Sambuc   if ( (n = strlen(save)) == 0) e(5);
158*433d6423SLionel Sambuc 
159*433d6423SLionel Sambuc   /* Check login against passwd file. First lookup login in /etc/passwd. */
160*433d6423SLionel Sambuc   if (n == 0) return;		/* if login not found, don't look it up */
161*433d6423SLionel Sambuc   if ( (stream = fopen(passwd_file, "r")) == NULL) e(8);
162*433d6423SLionel Sambuc   while (fgets(array, sizeof(array), stream) != NULL) {
163*433d6423SLionel Sambuc 	if (strncmp(array, save, n) == 0) {
164*433d6423SLionel Sambuc 		p = &array[0];		/* hunt for uid */
165*433d6423SLionel Sambuc 		while (*p != ':') p++;
166*433d6423SLionel Sambuc 		p++;
167*433d6423SLionel Sambuc 		while (*p != ':') p++;
168*433d6423SLionel Sambuc 		p++;			/* p now points to uid */
169*433d6423SLionel Sambuc 		etc_uid = atoi(p);
170*433d6423SLionel Sambuc 		if (etc_uid != ruid) e(9);
171*433d6423SLionel Sambuc 		break;			/* 1 entry per login please */
172*433d6423SLionel Sambuc 	}
173*433d6423SLionel Sambuc   }
174*433d6423SLionel Sambuc   fclose(stream);
175*433d6423SLionel Sambuc }
176*433d6423SLionel Sambuc 
test11d()177*433d6423SLionel Sambuc void test11d()
178*433d6423SLionel Sambuc {
179*433d6423SLionel Sambuc   int fd;
180*433d6423SLionel Sambuc   struct stat statbuf;
181*433d6423SLionel Sambuc 
182*433d6423SLionel Sambuc   subtest = 4;
183*433d6423SLionel Sambuc   fd = creat("T11.1", 0750);
184*433d6423SLionel Sambuc   if (fd < 0) e(1);
185*433d6423SLionel Sambuc   if (chown("T11.1", 8, 1) != 0) e(2);
186*433d6423SLionel Sambuc   if (chmod("T11.1", 0666) != 0) e(3);
187*433d6423SLionel Sambuc   if (stat("T11.1", &statbuf) != 0) e(4);
188*433d6423SLionel Sambuc   if ((statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0666) e(5);
189*433d6423SLionel Sambuc   if (close(fd) != 0) e(6);
190*433d6423SLionel Sambuc   if (unlink("T11.1") != 0) e(7);
191*433d6423SLionel Sambuc }
192*433d6423SLionel Sambuc 
193