+++ /dev/null
-#include <stdlib.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-extern const char **environ;
-
-
-#define SETUID 613 /* "pserver" user UID */
-#define SETGID 613 /* "pserver" group GID */
-#define PERMITTED_ENV_LIST "PWD"
-#define EXEC_PATHNAME "/usr/bin/cvs"
-
-
-#ifndef G_GNUC_NORETURN
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
-#define G_GNUC_NORETURN __attribute__((noreturn))
-#else /* !__GNUC__ */
-#define G_GNUC_NORETURN
-#endif /* !__GNUC__ */
-#endif /* !G_GNUC_NORETURN */
-
-#define EXITLOG(msg...) do {\
- openlog("pserverchroot",LOG_PID,LOG_DAEMON); \
- syslog(LOG_CRIT,msg); \
- closelog(); \
- exit(EXIT_FAILURE); \
- } while (0)
-
-#define LENGTH(x) (sizeof((x))/sizeof(*(x)))
-
-#define FUNCCHK(funcname,args...) do { \
- if (errno=0,funcname(args)) \
- funcfail( #funcname ); \
- } while (0)
-
-static void funcfail(const char *funcname) G_GNUC_NORETURN;
-static void funcfail(const char *funcname)
-{
- EXITLOG("Unable to %s(2): %s",funcname,strerror(errno));
-}
-
-int main(int argc,char **argv)
-{
-int total=0;
-const char *allowed[]={ PERMITTED_ENV_LIST };
-const char **allp,**envp;
-char *dup=NULL,*s;
-
-retry:
- for (envp=environ;*envp;envp++) {
- if (dup) free(dup);
- dup=strdup(*envp);
- if ((s=strchr(dup,'='))) *s='\0';
- for (allp=allowed;allp<allowed+LENGTH(allowed);allp++)
- if (!strcmp(dup,*allp)) goto ok;
- if (total++>1000)
- EXITLOG("Unable to clean environment for CVS pserver: %s",*envp);
- unsetenv(dup);
- goto retry;
-ok:;
- }
- FUNCCHK(setenv,"PATH","/usr/bin",1);
- FUNCCHK(chroot,"/home/short/pserver");
- FUNCCHK(chdir,"/");
- FUNCCHK(setgid,SETGID);
- FUNCCHK(setuid,SETUID);
- if (!getuid() || !geteuid() || !getgid() || !getegid())
- EXITLOG("Privileges NOT dropped!: uid=%d,euid=%d,gid=%d,egid=%d",
- getuid(),geteuid(),getgid(),getegid());
- errno=0,execv(EXEC_PATHNAME,argv);
- funcfail("execv");
-}