1 |
#include <errno.h> |
2 |
#include <string.h> |
3 |
#include <sys/types.h> |
4 |
#include <sys/stat.h> |
5 |
#include <stdio.h> |
6 |
#include <unistd.h> |
7 |
|
8 |
int canonicalize(char *buf, int bufsize, char *cwd, char *fn) |
9 |
{ |
10 |
int cwdsize = strlen(cwd); |
11 |
int fnsize = strlen(fn); |
12 |
if (fn[0] == '/') { |
13 |
if (fnsize +1 > bufsize) return ERANGE; |
14 |
strcpy(buf, fn); |
15 |
return 0; |
16 |
} |
17 |
if (cwdsize + 1 + fnsize + 1 > bufsize) return ERANGE; |
18 |
strcpy(buf, cwd); |
19 |
strcat(buf, "/"); |
20 |
strcat(buf, fn); |
21 |
return 0; |
22 |
} |
23 |
|
24 |
int main(int argc, char *argv[]) |
25 |
{ |
26 |
setuid(0); |
27 |
char *relfilename = "ifppc_up"; |
28 |
int relfilenamesize = strlen(relfilename); |
29 |
char cwdbuf[2048]; |
30 |
if (!getcwd(cwdbuf, sizeof cwdbuf)) { |
31 |
printf("CWD name too long (>%d bytes). move to a higher level directory.\n", (int)sizeof cwdbuf); |
32 |
return 1; |
33 |
} |
34 |
char filename[2048+128]; |
35 |
if (canonicalize(filename, sizeof filename, cwdbuf, argv[0])) { |
36 |
printf("unable to determine absolute executable filename. " |
37 |
"probably absolute filename too long (>%d bytes). " |
38 |
"move to a higher level directory.\n", (int)sizeof cwdbuf); |
39 |
return 1; |
40 |
} |
41 |
char *bs = strrchr(filename, '/'); |
42 |
if (!bs) { |
43 |
printf("???\n"); |
44 |
return 1; |
45 |
} |
46 |
int pathsize = bs-filename; |
47 |
if (pathsize + 1 + relfilenamesize + 1 > sizeof filename) { |
48 |
printf("absolute pathname too long (>%d bytes). " |
49 |
"move to a higher level directory.\n", (int)sizeof cwdbuf); |
50 |
return 1; |
51 |
} |
52 |
strcpy(bs+1, relfilename); |
53 |
// printf("filename = %s, uid=%d, euid=%d\n", filename, getuid(), geteuid()); |
54 |
struct stat s; |
55 |
if (stat(filename, &s)) { |
56 |
printf("can't stat file '%s': %s\n", filename, strerror(errno)); |
57 |
return 1; |
58 |
} |
59 |
if (s.st_uid != 0) { |
60 |
printf("script '%s' must be owned by root (UID %d instead)\n", filename, s.st_uid); |
61 |
return 1; |
62 |
} |
63 |
if (s.st_mode & S_IWGRP) { |
64 |
printf("script '%s' must not be group-writable\n", filename); |
65 |
return 1; |
66 |
} |
67 |
if (s.st_mode & S_IWOTH) { |
68 |
printf("script '%s' must not be world-writable\n", filename); |
69 |
return 1; |
70 |
} |
71 |
execl("/bin/sh", "/bin/sh", filename, (char*)NULL); |
72 |
return 0; |
73 |
} |