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