X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=client.c;h=523a7be3d1dd7ffd98c224b2a2678512fda5a9ff;hp=bc554128cff66cadc40098d6d4e2566edd2a2428;hb=70d3947fb471e0e12ef89c35f915f6acec217f4a;hpb=f7dd4f74d0a6b3399fe694f80911657aec351ffd diff --git a/client.c b/client.c index bc55412..523a7be 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 @@ -72,6 +72,7 @@ #include "config.h" #include "common.h" +#include "both.h" #include "version.h" enum fdmodifiervalues { @@ -127,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; @@ -213,7 +214,7 @@ static void NONRETURNPRINTFFORMAT(1,2) protoerror(const char *fmt, ...) { static void xfread(void *p, size_t sz, FILE *file) { size_t nr; - nr= fread(p,1,sz,file); + nr= working_fread(p,sz,file); if (nr != sz) protoreaderror(file,"in data"); } @@ -277,7 +278,8 @@ static void getprogress(struct progress_msg *progress_r, FILE *file) { protoerror("stderr message length %d is far too long", progress_r->data.errmsg.messagelen); for (i=0; idata.errmsg.messagelen; i++) { - c= getc(file); if (c==EOF) protoreaderror(file,"in error message"); + c= working_getc(file); + if (c==EOF) protoreaderror(file,"in error message"); if (isprint(c)) putc(c,stderr); else fprintf(stderr,"\\x%02x",(unsigned char)c); } @@ -378,6 +380,7 @@ static void sighandler_chld(int ignored) /* DOES return, unlike in daemon */ { memset(&event_mbuf,0,sizeof(event_mbuf)); event_mbuf.magic= EVENT_MAGIC; event_mbuf.type= et_closereadfd; + event_mbuf.data.closereadfd.fd= fd; r= fwrite(&event_mbuf,1,sizeof(event_mbuf),swfile); if (r != sizeof(event_mbuf) || fflush(swfile)) if (errno != EPIPE) syscallerror("inform service of closed read fd"); @@ -433,8 +436,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"); @@ -679,7 +684,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" @@ -689,7 +694,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"); @@ -737,13 +742,14 @@ static void callvalueoption(const struct optioninfo *oip, char *arg) { char *equals; if (oip->values == 2) { equals= strchr(arg,'='); - if (!equals) + if (!equals) { if (oip->abbrev) usageerror("option --%s (-%c) passed argument `%s' with no `='", oip->full,oip->abbrev,arg); else usageerror("option --%s passed argument `%s' with no `='", oip->full,arg); + } *equals++= 0; (oip->fn)(oip,equals,arg); } else { @@ -851,18 +857,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= 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; @@ -872,9 +878,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; @@ -884,7 +890,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"); @@ -1046,7 +1052,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; @@ -1065,7 +1071,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); @@ -1128,6 +1134,7 @@ static void connect_pipes(void) { struct sigaction sig; char catnamebuf[sizeof(int)*3+30]; int fd, reading; + pid_t child; for (fd=0; fd