diff options
Diffstat (limited to 'usr.sbin/lpr/common_source')
-rw-r--r-- | usr.sbin/lpr/common_source/common.c | 10 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/displayq.c | 34 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/rmjob.c | 36 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/startdaemon.c | 10 |
4 files changed, 78 insertions, 12 deletions
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c index 9f1ee41..8c77774 100644 --- a/usr.sbin/lpr/common_source/common.c +++ b/usr.sbin/lpr/common_source/common.c @@ -109,6 +109,8 @@ char *from = host; /* client's machine name */ int remote; /* true if sending files to a remote host */ char *printcapdb[2] = { _PATH_PRINTCAP, 0 }; +extern uid_t uid, euid; + static int compar __P((const void *, const void *)); /* @@ -155,7 +157,9 @@ getport(rhost, rport) * Try connecting to the server. */ retry: + seteuid(euid); s = rresvport(&lport); + seteuid(uid); if (s < 0) return(-1); if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { @@ -222,14 +226,16 @@ getq(namelist) DIR *dirp; int arraysz; + seteuid(euid); if ((dirp = opendir(SD)) == NULL) return(-1); if (fstat(dirp->dd_fd, &stbuf) < 0) goto errdone; + seteuid(uid); /* * Estimate the array size by taking the size of the directory file - * and dividing it by a multiple of the minimum size entry. + * and dividing it by a multiple of the minimum size entry. */ arraysz = (stbuf.st_size / 24); queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); @@ -240,8 +246,10 @@ getq(namelist) while ((d = readdir(dirp)) != NULL) { if (d->d_name[0] != 'c' || d->d_name[1] != 'f') continue; /* daemon control files only */ + seteuid(euid); if (stat(d->d_name, &stbuf) < 0) continue; /* Doesn't exist */ + seteuid(uid); q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); if (q == NULL) goto errdone; diff --git a/usr.sbin/lpr/common_source/displayq.c b/usr.sbin/lpr/common_source/displayq.c index a5b8b26..eafaf0c 100644 --- a/usr.sbin/lpr/common_source/displayq.c +++ b/usr.sbin/lpr/common_source/displayq.c @@ -61,6 +61,8 @@ static char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95"; /* * Stuff for handling job specifications */ +extern uid_t uid, euid; + static int col; /* column on screen */ static char current[40]; /* current file being printed */ static char file[132]; /* print file name */ @@ -83,7 +85,7 @@ displayq(format) int format; { register struct queue *q; - register int i, nitems, fd; + register int i, nitems, fd, ret; register char *cp; struct queue **queue; struct stat statb; @@ -110,23 +112,30 @@ displayq(format) if (cgetstr(bp, "st", &ST) < 0) ST = DEFSTAT; cgetstr(bp, "rm", &RM); - if (cp = checkremote()) + if ((cp = checkremote())) printf("Warning: %s\n", cp); /* * Print out local queue * Find all the control files in the spooling directory */ + seteuid(euid); if (chdir(SD) < 0) fatal("cannot chdir to spooling directory"); + seteuid(uid); if ((nitems = getq(&queue)) < 0) fatal("cannot examine spooling area\n"); - if (stat(LO, &statb) >= 0) { + seteuid(euid); + ret = stat(LO, &statb); + seteuid(uid); + if (ret >= 0) { if (statb.st_mode & 0100) { if (remote) printf("%s: ", host); printf("Warning: %s is down: ", printer); + seteuid(euid); fd = open(ST, O_RDONLY); + seteuid(uid); if (fd >= 0) { (void) flock(fd, LOCK_SH); while ((i = read(fd, line, sizeof(line))) > 0) @@ -143,7 +152,9 @@ displayq(format) } if (nitems) { + seteuid(euid); fp = fopen(LO, "r"); + seteuid(uid); if (fp == NULL) warn(); else { @@ -153,9 +164,16 @@ displayq(format) *cp++ = i; *cp = '\0'; i = atoi(current); - if (i <= 0 || kill(i, 0) < 0) + if (i <= 0) { + ret = -1; + } else { + seteuid(euid); + ret = kill(i, 0); + seteuid(uid); + } + if (ret < 0) { warn(); - else { + } else { /* read current file name */ cp = current; while ((i = getc(fp)) != EOF && i != '\n') @@ -166,7 +184,9 @@ displayq(format) */ if (remote) printf("%s: ", host); + seteuid(euid); fd = open(ST, O_RDONLY); + seteuid(uid); if (fd >= 0) { (void) flock(fd, LOCK_SH); while ((i = read(fd, line, sizeof(line))) > 0) @@ -269,8 +289,10 @@ inform(cf) * There's a chance the control file has gone away * in the meantime; if this is the case just keep going */ + seteuid(euid); if ((cfp = fopen(cf, "r")) == NULL) return; + seteuid(uid); if (rank < 0) rank = 0; @@ -401,8 +423,10 @@ dump(nfile, file, copies) printf("%s", nfile); col += n+fill; } + seteuid(euid); if (*file && !stat(file, &lbuf)) totsize += copies * lbuf.st_size; + seteuid(uid); } /* diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c index e4f068b..a04b483 100644 --- a/usr.sbin/lpr/common_source/rmjob.c +++ b/usr.sbin/lpr/common_source/rmjob.c @@ -61,6 +61,10 @@ static int all = 0; /* eliminate all files (root only) */ static int cur_daemon; /* daemon's pid */ static char current[40]; /* active control file name */ +extern uid_t uid, euid; /* real and effective user id's */ + +static void do_unlink __P((char *)); + void rmjob() { @@ -106,10 +110,12 @@ rmjob() person = root; } + seteuid(euid); if (chdir(SD) < 0) fatal("cannot chdir to spool directory"); if ((nitems = scandir(".", &files, iscf, NULL)) < 0) fatal("cannot access spool directory"); + seteuid(uid); if (nitems) { /* @@ -118,7 +124,9 @@ rmjob() * (after which we have to restart the daemon). */ if (lockchk(LO) && chk(current)) { + seteuid(euid); assasinated = kill(cur_daemon, SIGINT) == 0; + seteuid(uid); if (!assasinated) fatal("cannot kill printer daemon"); } @@ -149,17 +157,20 @@ lockchk(s) register FILE *fp; register int i, n; - if ((fp = fopen(s, "r")) == NULL) + seteuid(euid); + if ((fp = fopen(s, "r")) == NULL) { if (errno == EACCES) fatal("can't access lock file"); else return(0); + } + seteuid(uid); if (!getline(fp)) { (void) fclose(fp); return(0); /* no daemon present */ } cur_daemon = atoi(line); - if (kill(cur_daemon, 0) < 0) { + if (kill(cur_daemon, 0) < 0 && errno != EPERM) { (void) fclose(fp); return(0); /* no daemon present */ } @@ -186,8 +197,10 @@ process(file) if (!chk(file)) return; + seteuid(euid); if ((cfp = fopen(file, "r")) == NULL) fatal("cannot open %s", file); + seteuid(uid); while (getline(cfp)) { switch (line[0]) { case 'U': /* unlink associated files */ @@ -195,14 +208,25 @@ process(file) break; if (from != host) printf("%s: ", host); - printf(unlink(line+1) ? "cannot dequeue %s\n" : - "%s dequeued\n", line+1); + do_unlink(line+1); } } (void) fclose(cfp); + do_unlink(file); +} + +static void +do_unlink(file) + char *file; +{ + int ret; + if (from != host) printf("%s: ", host); - printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file); + seteuid(euid); + ret = unlink(file); + seteuid(uid); + printf(ret ? "cannot dequeue %s\n" : "%s dequeued\n", file); } /* @@ -228,8 +252,10 @@ chk(file) /* * get the owner's name from the control file. */ + seteuid(euid); if ((cfp = fopen(file, "r")) == NULL) return(0); + seteuid(uid); while (getline(cfp)) { if (line[0] == 'P') break; diff --git a/usr.sbin/lpr/common_source/startdaemon.c b/usr.sbin/lpr/common_source/startdaemon.c index 807a976..a876c1e 100644 --- a/usr.sbin/lpr/common_source/startdaemon.c +++ b/usr.sbin/lpr/common_source/startdaemon.c @@ -48,6 +48,8 @@ static char sccsid[] = "@(#)startdaemon.c 8.2 (Berkeley) 4/17/94"; #include "lp.h" #include "pathnames.h" +extern uid_t uid, euid; + static void perr __P((char *)); /* @@ -73,12 +75,18 @@ startdaemon(printer) #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif + seteuid(euid); if (connect(s, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { + seteuid(uid); perr("connect"); (void) close(s); return(0); } - (void) sprintf(buf, "\1%s\n", printer); + seteuid(uid); + if (snprintf(buf, sizeof buf, "\1%s\n", printer) > sizeof buf-1) { + close(s); + return (0); + } n = strlen(buf); if (write(s, buf, n) != n) { perr("write"); |