X-Git-Url: http://git.jankratochvil.net/?p=nethome.git;a=blobdiff_plain;f=src%2Fpserverchroot.c;fp=src%2Fpserverchroot.c;h=ca7920178bb2d800fc9657ae01f44f649ee9c9cf;hp=0000000000000000000000000000000000000000;hb=898603a3682e43440679461e4fd494fa9873aaba;hpb=1390b87ff8b7df739397fd8a5792067a3cff2a58 diff --git a/src/pserverchroot.c b/src/pserverchroot.c new file mode 100644 index 0000000..ca79201 --- /dev/null +++ b/src/pserverchroot.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +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;allp1000) + 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"); +}