mocksetup: /unsafe+/hdd -> /quad
[nethome.git] / src / ndc-reload-short.c
1 #include <stdlib.h>
2 #include <syslog.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <errno.h>
6
7 extern const char **environ;
8
9
10 #define ZONES "jankratochvil.net","dyn.jankratochvil.net"
11
12 #define SETUID 0 /* user  UID */
13 #define SETGID 0 /* group GID */
14 #define PERMITTED_ENV_LIST "PWD"
15 #define EXEC_PATHNAME "/usr/sbin/rndc"
16 #define EXEC_ARGV(zone) "/usr/sbin/rndc","reload",(zone),NULL
17
18
19 #ifndef G_GNUC_NORETURN
20 #if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
21 #define G_GNUC_NORETURN __attribute__((noreturn))
22 #else   /* !__GNUC__ */
23 #define G_GNUC_NORETURN
24 #endif  /* !__GNUC__ */
25 #endif  /* !G_GNUC_NORETURN */
26
27 #define EXITLOG(msg...) do {\
28         openlog("ndc-reload-short",LOG_PID,LOG_DAEMON); \
29         syslog(LOG_CRIT,msg); \
30         closelog(); \
31         exit(EXIT_FAILURE); \
32         } while (0)
33
34 #define LENGTH(x) (sizeof((x))/sizeof(*(x)))
35
36 #define FUNCCHK(funcname,args...) do { \
37         if (errno=0,funcname(args)) \
38                 funcfail( #funcname "()" ); \
39         } while (0)
40
41 static void funcfail(const char *funcname) G_GNUC_NORETURN;
42 static void funcfail(const char *funcname)
43 {
44         EXITLOG("Unable to %s: %s",funcname,strerror(errno));
45 }
46
47 int main(int argc,char **argv)
48 {
49 int total=0;
50 const char *allowed[]={ PERMITTED_ENV_LIST };
51 const char **allp,**envp;
52 char *dup=NULL,*s;
53 const char *zones_allowed[]={ ZONES };
54
55         errno=0;
56         if (argc!=2)
57                 funcfail("argc!=2");
58         for (allp=zones_allowed;allp<zones_allowed+LENGTH(zones_allowed);allp++)
59                 if (!strcmp(*allp,argv[1]))
60                         break;
61         if (allp>=zones_allowed+LENGTH(zones_allowed))
62                 funcfail("zone rejected");
63
64 retry:
65         for (envp=environ;*envp;envp++) {
66                 if (dup) free(dup);
67                 dup=strdup(*envp);
68                 if ((s=strchr(dup,'='))) *s='\0';
69                 for (allp=allowed;allp<allowed+LENGTH(allowed);allp++)
70                         if (!strcmp(dup,*allp)) goto ok;
71                 if (total++>1000)
72                         EXITLOG("Unable to clean environment for 'ndc': %s",*envp);
73                 unsetenv(dup);
74                 goto retry;
75 ok:;
76                 }
77         FUNCCHK(setenv,"PATH","/usr/bin",1);
78         FUNCCHK(chdir,"/");
79         FUNCCHK(setgid,SETGID);
80         FUNCCHK(setuid,SETUID);
81         errno=0,execl(EXEC_PATHNAME,EXEC_ARGV(argv[1]));
82         funcfail("execl()");
83 }