1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/*
* Suid wrapper for ikisite. Can run subcommands that allow themselves to
* be run via a wrapper.
*
* To ensure only site owners can change their sites,
* this wrapper expects the environment variable IKISITE_NONCE to be
* set to contain a previously created nonce for the site.
*
* An exception is the create, branch, list, checksite, sitelookup,
* enabledns, and updatecustomersite subcommands, which do not need a
* nonce to be set.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
extern char **environ;
int main (int argc, char **argv) {
int i;
char *args[argc+2];
char *nonce=getenv("IKISITE_NONCE");
if (!nonce) {
if (! argv[1] ||
strcmp(argv[1], "create") == 0 ||
strcmp(argv[1], "branch") == 0 ||
strcmp(argv[1], "list") == 0 ||
strcmp(argv[1], "sitelookup") == 0 ||
strcmp(argv[1], "getsetup") == 0 ||
strcmp(argv[1], "updatecustomersite") == 0 ||
strcmp(argv[1], "checksite") == 0 ||
strcmp(argv[1], "enabledns") == 0) {
/* use a dummy value so ikisite still can tell
* it is being run from the wrapper */
nonce="dummy";
}
else {
fprintf(stderr, "IKISITE_NONCE not set\n");
exit(1);
}
}
/* suid safety */
#ifdef __TINYC__
/* old tcc versions do not support modifying environ directly */
if (clearenv() != 0) {
perror("clearenv");
exit(1);
}
#else
/* this is more portable on freebsd/osx, which lack clearenv */
*environ = NULL;
#endif
if (setenv("PATH", "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin", 1) != 0) {
perror("setenv");
exit(1);
}
if (setenv("IKISITE_NONCE", nonce, 1) != 0) {
perror("setenv");
exit(1);
}
if (setregid(0, 0) != 0) {
perror("setregid");
exit(1);
}
if (setreuid(0, 0) != 0) {
perror("setreuid");
exit(1);
}
/* Pass argv to ikisite. */
args[0]="/usr/bin/ikisite";
for (i=1; i<argc; i++) {
args[i]=argv[i];
}
args[i]=NULL;
execv(args[0], args);
perror(args[0]);
exit(1);
}
|