X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=client.c;h=3d70f2bcb6a01cc8b09d50722e5212032fb1d3a4;hp=4987073a3de76dad9d9dcbe55e85ab7cb5b99a37;hb=f01eaa6588a9dc2673bd35d1c1be043976b9c09a;hpb=b6c671fd90134d458ad4722ec3a99742bced1a34 diff --git a/client.c b/client.c index 4987073..3d70f2b 100644 --- a/client.c +++ b/client.c @@ -2,7 +2,7 @@ * userv - client.c * client code * - * Copyright (C)1996-1997 Ian Jackson + * Copyright (C)1996-1997,1999 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 @@ -128,7 +128,7 @@ static uid_t myuid, spoofuid; static gid_t mygid, spoofgid, *gidarray; static int ngids; static struct opening_msg opening_mbuf; -static const char *logname; +static const char *loginname; static char *cwdbuf; static size_t cwdbufsize; static char *ovbuf; @@ -168,7 +168,7 @@ static void NONRETURNPRINTFFORMAT(1,2) miscerror(const char *fmt, ...) { exit(-1); } -static void NONRETURNPRINTFFORMAT(1,2) syscallerror(const char *fmt, ...) { +static void NONRETURNPRINTFFORMAT(1,2) fsyscallerror(const char *fmt, ...) { va_list al; int e; @@ -181,6 +181,10 @@ static void NONRETURNPRINTFFORMAT(1,2) syscallerror(const char *fmt, ...) { exit(-1); } +void syscallerror(const char *what) { + fsyscallerror("%s",what); +} + static void NONRETURNING protoreaderror(FILE *file, const char *where) { int e; @@ -300,18 +304,7 @@ static void getprogress(struct progress_msg *progress_r, FILE *file) { * the signal asynchronicity starts. They can do anything they like. */ -static void *xmalloc(size_t s) { - void *p; - p= malloc(s?s:1); - if (!p) syscallerror("malloc (%lu bytes)",(unsigned long)s); - return p; -} - -static void *xrealloc(void *p, size_t s) { - p= realloc(p,s); - if (!p) syscallerror("realloc (%lu bytes)",(unsigned long)s); - return p; -} +/* This includes xmalloc and xrealloc from both.c */ static void xfwritestring(const char *s, FILE *file) { int l; @@ -348,7 +341,7 @@ static void disconnect(void) /* DOES return, unlike in daemon */ { event_mbuf.type= et_disconnect; r= fwrite(&event_mbuf,1,sizeof(event_mbuf),swfile); if ((r != sizeof(event_mbuf) || fflush(swfile)) && errno != EPIPE) - syscallerror("write to server when disconnecting\n"); + syscallerror("write to server when disconnecting"); } systemerror= 1; } @@ -372,7 +365,6 @@ static void sighandler_chld(int ignored) /* DOES return, unlike in daemon */ { if (child == 0 || (child == -1 && errno == ECHILD)) break; if (child == -1) syscallerror("wait for child process (in sigchld handler)"); for (fd=0; fd=fdsetupsize) continue; /* perhaps the caller gave us children */ if ((WIFEXITED(status) && WEXITSTATUS(status)==0) || (WIFSIGNALED(status) && WTERMSIG(status)==SIGPIPE) || @@ -437,8 +429,10 @@ static void usage(void) { " --override-file } to root\n" " --spoof-user } or same user\n" "fdmodifiers: read write overwrite trunc[ate]\n" - "(separate with commas) append sync excl[usive] creat[e] fd\n\n" - "userv and uservd version " VERSION VEREXT "; copyright (C)1996-1997 Ian Jackson.\n" + "(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" "there is NO WARRANTY; type `userv --copyright' for details.\n", stderr) < 0) syscallerror("write usage to stderr"); @@ -589,9 +583,9 @@ static void of_file(const struct optioninfo *oip, const char *value, char *key) } r= fstat(copyfd,&stab); if (r) { - if (oip) syscallerror("check filedescriptor %lu (named as target of file " - "descriptor redirection for %lu)",copyfd,fd); - else syscallerror("check basic filedescriptor %lu at program start",copyfd); + if (oip) fsyscallerror("check filedescriptor %lu (named as target of file " + "descriptor redirection for %lu)",copyfd,fd); + else fsyscallerror("check basic filedescriptor %lu at program start",copyfd); } fdsetup[fd].copyfd= copyfd; } @@ -683,7 +677,7 @@ static void of_help(const struct optioninfo *oip, const char *value, char *key) static void of_copyright(const struct optioninfo *oip, const char *value, char *key) { if (fputs( -" userv - user service daemon and client; copyright (C)1996-1997 Ian Jackson\n\n" +" userv - user service daemon and client; copyright (C)1996-1999 Ian Jackson\n\n" " This is free software; you can redistribute it and/or modify it under the\n" " terms of the GNU General Public License as published by the Free Software\n" " Foundation; either version 2 of the License, or (at your option) any\n" @@ -693,7 +687,7 @@ static void of_copyright(const struct optioninfo *oip, const char *value, char * " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n" " Public License for more details.\n\n" " You should have received a copy of the GNU General Public License along\n" -" with userv; if not, write to Ian Jackson or\n" +" with userv; if not, write to Ian Jackson or\n" " to the Free Software Foundation, 59 Temple Place - Suite 330, Boston,\n" " MA 02111-1307, USA.\n", stdout) < 0) syscallerror("write usage to stderr"); @@ -856,18 +850,18 @@ static void determine_users(void) { spoofuid= myuid; spoofgid= mygid; - logname= getenv("LOGNAME"); - if (!logname) logname= getenv("USER"); - if (logname) { - pw= getpwnam(logname); - if (!pw || pw->pw_uid != myuid) logname= 0; + loginname= getenv("LOGNAME"); + if (!loginname) loginname= getenv("USER"); + if (loginname) { + pw= getpwnam(loginname); + if (!pw || pw->pw_uid != myuid) loginname= 0; } - if (!logname) { + if (!loginname) { pw= getpwuid(myuid); if (!pw) miscerror("cannot determine your login name"); - logname= pw->pw_name; + loginname= xstrsave(pw->pw_name); } - if (!strcmp(serviceuser,"-")) serviceuser= logname; + if (!strcmp(serviceuser,"-")) serviceuser= loginname; pw= getpwnam(serviceuser); if (!pw) miscerror("requested service user `%s' is not a user",serviceuser); serviceuid= pw->pw_uid; @@ -877,9 +871,9 @@ static void determine_users(void) { " the user who will be providing the service"); if (spoofuser) { - logname= spoofuser; - pw= getpwnam(logname); - if (!pw) miscerror("spoofed login name `%s' is not valid",logname); + loginname= spoofuser; + pw= getpwnam(loginname); + if (!pw) miscerror("spoofed login name `%s' is not valid",loginname); spoofuid= pw->pw_uid; spoofgid= pw->pw_gid; ngidssize= ngids; ngids= 0; @@ -889,7 +883,7 @@ static void determine_users(void) { } gidarray[ngids++]= spoofgid; while ((gr= getgrent())) { /* ouch! getgrent has no error behaviour! */ - for (mem= gr->gr_mem; *mem && strcmp(*mem,logname); mem++); + for (mem= gr->gr_mem; *mem && strcmp(*mem,loginname); mem++); if (!*mem) continue; if (ngids>=ngidssize) { if (ngids>=MAX_GIDS) miscerror("spoofed user is member of too many groups"); @@ -945,7 +939,7 @@ static void process_override(const char *servicename) { break; case ot_file: ovfile= fopen(overridevalue,"r"); - if (!ovfile) syscallerror("open overriding configuration file `%s'",overridevalue); + if (!ovfile) fsyscallerror("open overriding configuration file `%s'",overridevalue); ovbuf= 0; ovavail= ovused= 0; while ((c= getc(ovfile)) != EOF) { if (!c) miscerror("overriding config file `%s' contains null(s)",overridevalue); @@ -957,7 +951,7 @@ static void process_override(const char *servicename) { ovbuf[ovused++]= c; } if (ferror(ovfile) || fclose(ovfile)) - syscallerror("read overriding configuration file `%s'",overridevalue); + fsyscallerror("read overriding configuration file `%s'",overridevalue); ovbuf= xrealloc(ovbuf,ovused+1); ovbuf[ovused]= 0; break; @@ -994,7 +988,7 @@ static int server_connect(void) { if (errno == ECONNREFUSED || errno == ENOENT) syscallerror("uservd daemon is not running - service not available"); if (errno != EINTR) - syscallerror("unable to connect to uservd daemon: %m"); + fsyscallerror("unable to connect to uservd daemon: %m"); } return sfd; @@ -1027,16 +1021,16 @@ static void server_preparepipes(void) { assert(!pipepathbuf[PIPEPATHMAXLEN]); priv_resume(); if (unlink(pipepathbuf) && errno != ENOENT) - syscallerror("remove any old pipe `%s'",pipepathbuf); + fsyscallerror("remove any old pipe `%s'",pipepathbuf); if (mkfifo(pipepathbuf,0600)) /* permissions are irrelevant */ - syscallerror("create pipe `%s'",pipepathbuf); + fsyscallerror("create pipe `%s'",pipepathbuf); tempfd= open(pipepathbuf,O_RDWR); - if (tempfd<0) syscallerror("prelim open pipe `%s' for read+write",pipepathbuf); + if (tempfd<0) fsyscallerror("prelim open pipe `%s' for read+write",pipepathbuf); assert(fdsetup[fd].mods & (fdm_read|fdm_write)); fdsetup[fd].pipefd= open(pipepathbuf, (fdsetup[fd].mods & fdm_read) ? O_WRONLY : O_RDONLY); - if (fdsetup[fd].pipefd<0) syscallerror("real open pipe `%s'",pipepathbuf); - if (close(tempfd)) syscallerror("close prelim fd onto pipe `%s'",pipepathbuf); + if (fdsetup[fd].pipefd<0) fsyscallerror("real open pipe `%s'",pipepathbuf); + if (close(tempfd)) fsyscallerror("close prelim fd onto pipe `%s'",pipepathbuf); priv_suspend(); } } @@ -1051,7 +1045,7 @@ static void server_sendrequest(int argc, char *const *argv) { request_mbuf.clientpid= getpid(); request_mbuf.serviceuserlen= strlen(serviceuser); request_mbuf.servicelen= strlen(argv[0]); - request_mbuf.lognamelen= strlen(logname); + request_mbuf.loginnamelen= strlen(loginname); request_mbuf.spoofed= spoofuser ? 1 : 0; request_mbuf.cwdlen= cwdbufsize; request_mbuf.callinguid= spoofuid; @@ -1070,7 +1064,7 @@ static void server_sendrequest(int argc, char *const *argv) { xfwrite(&request_mbuf,sizeof(request_mbuf),swfile); xfwrite(serviceuser,sizeof(*serviceuser)*request_mbuf.serviceuserlen,swfile); xfwrite(argv[0],sizeof(*argv[0])*request_mbuf.servicelen,swfile); - xfwrite(logname,sizeof(*logname)*request_mbuf.lognamelen,swfile); + xfwrite(loginname,sizeof(*loginname)*request_mbuf.loginnamelen,swfile); xfwrite(cwdbuf,sizeof(*cwdbuf)*request_mbuf.cwdlen,swfile); if (ovused>=0) xfwrite(ovbuf,sizeof(*ovbuf)*ovused,swfile); xfwrite(&spoofgid,sizeof(gid_t),swfile); @@ -1141,13 +1135,13 @@ static void connect_pipes(void) { fdsetup[fd].copyfd= open(fdsetup[fd].filename,fdsetup[fd].oflags|O_NOCTTY,0777); if (fdsetup[fd].copyfd<0) - syscallerror("open file `%s' for fd %d",fdsetup[fd].filename,fd); + fsyscallerror("open file `%s' for fd %d",fdsetup[fd].filename,fd); } blocksignals(SIG_BLOCK); child= fork(); fdsetup[fd].catpid= child; blocksignals(SIG_UNBLOCK); - if (child==-1) syscallerror("fork for cat for fd %d",fd); + if (child==-1) fsyscallerror("fork for cat for fd %d",fd); if (!child) { snprintf(catnamebuf,sizeof(catnamebuf),"cat fd%d",fd); catnamebuf[sizeof(catnamebuf)-1]= 0; @@ -1167,8 +1161,8 @@ static void connect_pipes(void) { exit(-1); } if (fdsetup[fd].copyfd>2) - if (close(fdsetup[fd].copyfd)) syscallerror("close real fd for %d",fd); - if (close(fdsetup[fd].pipefd)) syscallerror("close pipe fd for %d",fd); + if (close(fdsetup[fd].copyfd)) fsyscallerror("close real fd for %d",fd); + if (close(fdsetup[fd].pipefd)) fsyscallerror("close pipe fd for %d",fd); } } @@ -1203,7 +1197,7 @@ static void dispose_remaining_pipes(void) { blocksignals(SIG_BLOCK); for (fd=0; fd