7 extern const char **environ;
10 #define SETUID 613 /* "pserver" user UID */
11 #define SETGID 613 /* "pserver" group GID */
12 #define PERMITTED_ENV_LIST "PWD"
13 #define EXEC_PATHNAME "/usr/bin/cvs"
16 #ifndef G_GNUC_NORETURN
17 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
18 #define G_GNUC_NORETURN __attribute__((noreturn))
20 #define G_GNUC_NORETURN
21 #endif /* !__GNUC__ */
22 #endif /* !G_GNUC_NORETURN */
24 #define EXITLOG(msg...) do {\
25 openlog("pserverchroot",LOG_PID,LOG_DAEMON); \
26 syslog(LOG_CRIT,msg); \
31 #define LENGTH(x) (sizeof((x))/sizeof(*(x)))
33 #define FUNCCHK(funcname,args...) do { \
34 if (errno=0,funcname(args)) \
35 funcfail( #funcname ); \
38 static void funcfail(const char *funcname) G_GNUC_NORETURN;
39 static void funcfail(const char *funcname)
41 EXITLOG("Unable to %s(2): %s",funcname,strerror(errno));
44 int main(int argc,char **argv)
47 const char *allowed[]={ PERMITTED_ENV_LIST };
48 const char **allp,**envp;
52 for (envp=environ;*envp;envp++) {
55 if ((s=strchr(dup,'='))) *s='\0';
56 for (allp=allowed;allp<allowed+LENGTH(allowed);allp++)
57 if (!strcmp(dup,*allp)) goto ok;
59 EXITLOG("Unable to clean environment for CVS pserver: %s",*envp);
64 FUNCCHK(setenv,"PATH","/usr/bin",1);
65 FUNCCHK(chroot,"/home/short/pserver");
67 FUNCCHK(setgid,SETGID);
68 FUNCCHK(setuid,SETUID);
69 if (!getuid() || !geteuid() || !getgid() || !getegid())
70 EXITLOG("Privileges NOT dropped!: uid=%d,euid=%d,gid=%d,egid=%d",
71 getuid(),geteuid(),getgid(),getegid());
72 errno=0,execv(EXEC_PATHNAME,argv);