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