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