source: trunk/minix/test/test11.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 4.8 KB
Line 
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#define MAX_ERROR 1
15
16int errct, subtest;
17char *envp[3] = {"spring", "summer", 0};
18char *passwd_file = "/etc/passwd";
19
20_PROTOTYPE(int main, (int argc, char *argv[]));
21_PROTOTYPE(void test11a, (void));
22_PROTOTYPE(void test11b, (void));
23_PROTOTYPE(void test11c, (void));
24_PROTOTYPE(void test11d, (void));
25_PROTOTYPE(void e, (int n));
26
27int main(argc, argv)
28int argc;
29char *argv[];
30{
31 int i, m = 0xFFFF;
32
33 if (argc == 2) m = atoi(argv[1]);
34
35 printf("Test 11 ");
36 fflush(stdout); /* have to flush for child's benefit */
37
38 if (geteuid() != 0) {
39 printf("must be setuid root; test aborted\n");
40 exit(1);
41 }
42 if (getuid() == 0) {
43 printf("must be setuid root logged in as someone else; test aborted\n");
44 exit(1);
45 }
46
47/*
48 system("rm -rf DIR_11; mkdir DIR_11");
49 chdir("DIR_11");
50*/
51
52 for (i = 0; i < ITERATIONS; i++) {
53 if (m & 0001) test11a();
54 if (m & 0002) test11b();
55 if (m & 0004) test11c();
56 if (m & 0010) test11d();
57 }
58 if (errct == 0)
59 printf("ok\n");
60 else
61 printf(" %d errors\n", errct);
62
63/*
64 chdir("..");
65 system("rm -rf DIR_11");
66*/
67 return(0);
68}
69
70void test11a()
71{
72/* Test exec */
73 int n, fd;
74 char aa[4];
75
76 subtest = 1;
77
78 if (fork()) {
79 wait(&n);
80 if (n != 25600) e(1);
81 unlink("t1");
82 unlink("t2");
83 } else {
84 if (chown("t11a", 10, 20) < 0) e(2);
85 chmod("t11a", 0666);
86
87 /* The following call should fail because the mode has no X
88 * bits on. If a bug lets it unexpectedly succeed, the child
89 * will print an error message since the arguments are wrong.
90 */
91 execl("t11a", (char *) 0, envp); /* should fail -- no X bits */
92
93 /* Control should come here after the failed execl(). */
94 chmod("t11a", 06555);
95 if ((fd = creat("t1", 0600)) != 3) e(3);
96 if (close(fd) < 0) e(4);
97 if (open("t1", O_RDWR) != 3) e(5);
98 if (chown("t1", 10, 99) < 0) e(6);
99 if ((fd = creat("t2", 0060)) != 4) e(7);
100 if (close(fd) < 0) e(8);
101 if (open("t2", O_RDWR) != 4) e(9);
102 if (chown("t2", 99, 20) < 0) e(10);
103 if (setgid(6) < 0) e(11);
104 if (setuid(5) < 0) e(12);
105 if (getuid() != 5) e(13);
106 if (geteuid() != 5) e(14);
107 if (getgid() != 6) e(15);
108 if (getegid() != 6) e(16);
109 aa[0] = 3;
110 aa[1] = 5;
111 aa[2] = 7;
112 aa[3] = 9;
113 if (write(3, aa, 4) != 4) e(17);
114 lseek(3, 2L, 0);
115 execle("t11a", "t11a", "arg0", "arg1", "arg2", (char *) 0, envp);
116 e(18);
117 printf("Can't exec t11a\n");
118 exit(3);
119 }
120}
121
122void test11b()
123{
124 int n;
125 char *argv[5];
126
127 subtest = 2;
128 if (fork()) {
129 wait(&n);
130 if (n != (75 << 8)) e(20);
131 } else {
132 /* Child tests execv. */
133 argv[0] = "t11b";
134 argv[1] = "abc";
135 argv[2] = "defghi";
136 argv[3] = "j";
137 argv[4] = 0;
138 execv("t11b", argv);
139 e(19);
140 }
141}
142
143void test11c()
144{
145/* Test getlogin() and cuserid(). This test MUST run setuid root. */
146
147 int n, etc_uid;
148 uid_t ruid, euid;
149 char *lnamep, *cnamep, *p;
150 char array[L_cuserid], save[L_cuserid], save2[L_cuserid];
151 FILE *stream;
152
153 subtest = 3;
154 errno = -2000; /* None of these calls set errno. */
155 array[0] = '@';
156 array[1] = '0';
157 save[0] = '#';
158 save[1] = '0';
159 ruid = getuid();
160 euid = geteuid();
161 lnamep = getlogin();
162 strcpy(save, lnamep);
163 cnamep = cuserid(array);
164 strcpy(save2, cnamep);
165
166 /* Because we are setuid root, cuser == array == 'root'; login != 'root' */
167 if (euid != 0) e(1);
168 if (ruid == 0) e(2);
169 if (strcmp(cnamep, "root") != 0) e(3);
170 if (strcmp(array, "root") != 0) e(4);
171 if ( (n = strlen(save)) == 0) e(5);
172 if (strcmp(save, cnamep) == 0) e(6); /* they must be different */
173 cnamep = cuserid(NULL);
174 if (strcmp(cnamep, save2) != 0) e(7);
175
176 /* Check login against passwd file. First lookup login in /etc/passwd. */
177 if (n == 0) return; /* if login not found, don't look it up */
178 if ( (stream = fopen(passwd_file, "r")) == NULL) e(8);
179 while (fgets(array, L_cuserid, stream) != NULL) {
180 if (strncmp(array, save, n) == 0) {
181 p = &array[0]; /* hunt for uid */
182 while (*p != ':') p++;
183 p++;
184 while (*p != ':') p++;
185 p++; /* p now points to uid */
186 etc_uid = atoi(p);
187 if (etc_uid != ruid) e(9);
188 break; /* 1 entry per login please */
189 }
190 }
191 fclose(stream);
192}
193
194void test11d()
195{
196 int fd;
197 struct stat statbuf;
198
199 subtest = 4;
200 fd = creat("T11.1", 0750);
201 if (fd < 0) e(1);
202 if (chown("T11.1", 8, 1) != 0) e(2);
203 if (chmod("T11.1", 0666) != 0) e(3);
204 if (stat("T11.1", &statbuf) != 0) e(4);
205 if ((statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0666) e(5);
206 if (close(fd) != 0) e(6);
207 if (unlink("T11.1") != 0) e(7);
208}
209
210void e(n)
211int n;
212{
213 int err_num = errno; /* save errno in case printf clobbers it */
214
215 printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
216 errno = err_num; /* restore errno, just in case */
217 perror("");
218 if (errct++ > MAX_ERROR) {
219 printf("Too many errors; test aborted\n");
220 chdir("..");
221 system("rm -rf DIR*");
222 exit(1);
223 }
224}
Note: See TracBrowser for help on using the repository browser.