X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=client.c;h=520928f9d42e5c87056cc5912b1a13167a84ae81;hb=bc730637ae2abc44a1e1013bc64d85a92923cf6e;hp=9fb76df18c34be6822de85c953d57bc3d9a0ef7a;hpb=d44ffd2cdd131e70330e5e489dc5f524e82278f2;p=userv.git diff --git a/client.c b/client.c index 9fb76df..520928f 100644 --- a/client.c +++ b/client.c @@ -2,7 +2,7 @@ * userv - client.c * client code * - * Copyright (C)1996-1997,1999 Ian Jackson + * Copyright (C)1996-1997,1999-2001,2003 Ian Jackson * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -132,7 +132,7 @@ static const char *loginname; static char *cwdbuf; static size_t cwdbufsize; static char *ovbuf; -static int ovused, systemerror; +static int ovused, systemerror, socketfd; static void blocksignals(int how) { sigset_t set; @@ -432,7 +432,8 @@ static void usage(FILE *stream) { "(separate with commas) append sync excl[usive] creat[e] fd\n" "userv -B 'X' ... is same as userv --override 'execute-builtin X' - 'X' ...\n" " for help, type `userv -B help'; remember to quote multi-word X\n" - "userv and uservd version " VERSION VEREXT "; copyright (C)1996-1999 Ian Jackson.\n" + "userv and uservd version " VERSION VEREXT ".\n" + "Copyright (C)1996-2003,2006 Ian Jackson; copyright (C)2000 Ben Harris.\n" "there is NO WARRANTY; type `userv --copyright' for details.\n", stream) < 0) syscallerror("write usage message"); @@ -809,7 +810,7 @@ static void security_init(void) { mypid= getpid(); if (mypid == (pid_t)-1) syscallerror("getpid"); myuid= getuid(); if (myuid == (uid_t)-1) syscallerror("getuid"); mygid= getgid(); if (mygid == (gid_t)-1) syscallerror("getgid"); - ngids= getgroups(0,0); if (ngids == (gid_t)-1) syscallerror("getgroups(0,0)"); + ngids= getgroups(0,0); if (ngids == -1) syscallerror("getgroups(0,0)"); gidarray= xmalloc(sizeof(gid_t)*ngids); if (getgroups(ngids,gidarray) != ngids) syscallerror("getgroups(ngids,)"); @@ -1160,7 +1161,22 @@ static void prepare_asynchsignals(void) { if (sigaction(SIGALRM,&sig,0)) syscallerror("set up sigalrm handler"); if (!timeout) return; - if (alarm(timeout)<0) syscallerror("set up timeout alarm"); + alarm(timeout); +} + + +static void close_unwanted_pipes(void) { + int fd; + + for (fd=0; fd2) + if (close(fdsetup[fd].copyfd)) + if (errno != EBADF) + /* EBADF can be induced if cmd line specifies same fd twice */ + fsyscallerror("close real fd for %d",fd); + } } static void catdup(const char *which, int from, int to) { @@ -1205,14 +1221,15 @@ static void connect_pipes(void) { reading= fdsetup[fd].mods & fdm_read; catdup(catnamebuf, fdsetup[fd].copyfd, reading ? 0 : 1); catdup(catnamebuf, fdsetup[fd].pipefd, reading ? 1 : 0); + if (close(socketfd)) + fsyscallerror("%s: close client socket for for cat",catnamebuf); + close_unwanted_pipes(); execl("/bin/cat",catnamebuf,(char*)0); fprintf(stderr,"userv: %s: cannot exec `cat': %s\n",catnamebuf,strerror(errno)); exit(-1); } - if (fdsetup[fd].copyfd>2) - if (close(fdsetup[fd].copyfd)) fsyscallerror("close real fd for %d",fd); - if (close(fdsetup[fd].pipefd)) fsyscallerror("close pipe fd for %d",fd); } + close_unwanted_pipes(); } static void server_sendconfirm(void) { @@ -1312,7 +1329,7 @@ static void NONRETURNING process_exitstatus(int status) { } int main(int argc, char *const *argv) { - int status, socketfd; + int status; #ifdef NDEBUG # error Do not disable assertions in this security-critical code !