summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/lpr/common_source/common.c10
-rw-r--r--usr.sbin/lpr/common_source/displayq.c34
-rw-r--r--usr.sbin/lpr/common_source/rmjob.c36
-rw-r--r--usr.sbin/lpr/common_source/startdaemon.c10
-rw-r--r--usr.sbin/lpr/lpc/cmds.c81
-rw-r--r--usr.sbin/lpr/lpc/lpc.c16
-rw-r--r--usr.sbin/lpr/lpd/lpd.c17
-rw-r--r--usr.sbin/lpr/lpq/lpq.c5
-rw-r--r--usr.sbin/lpr/lpr/lpr.c32
-rw-r--r--usr.sbin/lpr/lprm/lprm.c4
-rw-r--r--usr.sbin/lpr/pac/pac.c4
11 files changed, 199 insertions, 50 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");
diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c
index 95e46ba..36a2dd2 100644
--- a/usr.sbin/lpr/lpc/cmds.c
+++ b/usr.sbin/lpr/lpc/cmds.c
@@ -66,6 +66,8 @@ static char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/28/95";
#include "extern.h"
#include "pathnames.h"
+extern uid_t uid, euid;
+
static void abortpr __P((int));
static void cleanpr __P((void));
static void disablepr __P((void));
@@ -102,7 +104,8 @@ doabort(argc, argv)
while (cgetnext(&bp, printcapdb) > 0) {
cp1 = prbuf;
cp2 = bp;
- while ((c = *cp2++) && c != '|' && c != ':')
+ while ((c = *cp2++) && c != '|' && c != ':' &&
+ (cp1 - prbuf) < sizeof(prbuf))
*cp1++ = c;
*cp1 = '\0';
abortpr(1);
@@ -135,13 +138,14 @@ abortpr(dis)
SD = _PATH_DEFSPOOL;
if (cgetstr(bp, "lo", &LO) == -1)
LO = DEFLOCK;
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
printf("%s:\n", printer);
/*
* Turn on the owner execute bit of the lock file to disable printing.
*/
if (dis) {
+ seteuid(euid);
if (stat(line, &stbuf) >= 0) {
if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
printf("\tcannot disable printing\n");
@@ -158,10 +162,10 @@ abortpr(dis)
printf("\tprinting disabled\n");
printf("\tno daemon to abort\n");
}
- return;
+ goto out;
} else {
printf("\tcannot stat lock file\n");
- return;
+ goto out;
}
}
/*
@@ -169,18 +173,23 @@ abortpr(dis)
*/
if ((fp = fopen(line, "r")) == NULL) {
printf("\tcannot open lock file\n");
- return;
+ goto out;
}
if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
(void) fclose(fp); /* unlocks as well */
printf("\tno daemon to abort\n");
- return;
+ goto out;
}
(void) fclose(fp);
- if (kill(pid = atoi(line), SIGTERM) < 0)
- printf("\tWarning: daemon (pid %d) not killed\n", pid);
- else
+ if (kill(pid = atoi(line), SIGTERM) < 0) {
+ if (errno == ESRCH)
+ printf("\tno daemon to abort\n");
+ else
+ printf("\tWarning: daemon (pid %d) not killed\n", pid);
+ } else
printf("\tdaemon (pid %d) killed\n", pid);
+out:
+ seteuid(uid);
}
/*
@@ -305,11 +314,13 @@ cleanpr()
SD = _PATH_DEFSPOOL;
printf("%s:\n", printer);
- for (lp = line, cp = SD; (*lp++ = *cp++); )
+ for (lp = line, cp = SD; (lp - line) < sizeof(line) && (*lp++ = *cp++);)
;
lp[-1] = '/';
+ seteuid(euid);
nitems = scandir(SD, &queue, doselect, sortq);
+ seteuid(uid);
if (nitems < 0) {
printf("\tcannot examine spool directory\n");
return;
@@ -345,15 +356,17 @@ cleanpr()
}
} while (++i < nitems);
}
-
+
static void
unlinkf(name)
char *name;
{
+ seteuid(euid);
if (unlink(name) < 0)
printf("\tcannot remove %s\n", name);
else
printf("\tremoved %s\n", name);
+ seteuid(uid);
}
/*
@@ -408,18 +421,20 @@ enablepr()
SD = _PATH_DEFSPOOL;
if (cgetstr(bp, "lo", &LO) == -1)
LO = DEFLOCK;
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
printf("%s:\n", printer);
/*
* Turn off the group execute bit of the lock file to enable queuing.
*/
+ seteuid(euid);
if (stat(line, &stbuf) >= 0) {
if (chmod(line, stbuf.st_mode & 0767) < 0)
printf("\tcannot enable queuing\n");
else
printf("\tqueuing enabled\n");
}
+ seteuid(uid);
}
/*
@@ -475,11 +490,12 @@ disablepr()
SD = _PATH_DEFSPOOL;
if (cgetstr(bp, "lo", &LO) == -1)
LO = DEFLOCK;
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
printf("%s:\n", printer);
/*
* Turn on the group execute bit of the lock file to disable queuing.
*/
+ seteuid(euid);
if (stat(line, &stbuf) >= 0) {
if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
printf("\tcannot disable queuing\n");
@@ -492,9 +508,9 @@ disablepr()
(void) close(fd);
printf("\tqueuing disabled\n");
}
- return;
} else
printf("\tcannot stat lock file\n");
+ seteuid(uid);
}
/*
@@ -560,7 +576,8 @@ putmsg(argc, argv)
* Turn on the group execute bit of the lock file to disable queuing and
* turn on the owner execute bit of the lock file to disable printing.
*/
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
+ seteuid(euid);
if (stat(line, &stbuf) >= 0) {
if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
printf("\tcannot disable queuing\n");
@@ -573,18 +590,21 @@ putmsg(argc, argv)
(void) close(fd);
printf("\tprinter and queuing disabled\n");
}
+ seteuid(uid);
return;
} else
printf("\tcannot stat lock file\n");
/*
* Write the message into the status file.
*/
- (void) sprintf(line, "%s/%s", SD, ST);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, ST);
fd = open(line, O_WRONLY|O_CREAT, 0664);
if (fd < 0 || flock(fd, LOCK_EX) < 0) {
printf("\tcannot create status file\n");
+ seteuid(uid);
return;
}
+ seteuid(uid);
(void) ftruncate(fd, 0);
if (argc <= 0) {
(void) write(fd, "\n", 1);
@@ -713,12 +733,13 @@ startpr(enable)
SD = _PATH_DEFSPOOL;
if (cgetstr(bp, "lo", &LO) == -1)
LO = DEFLOCK;
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
printf("%s:\n", printer);
/*
* Turn off the owner execute bit of the lock file to enable printing.
*/
+ seteuid(euid);
if (enable && stat(line, &stbuf) >= 0) {
if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
printf("\tcannot enable printing\n");
@@ -729,6 +750,7 @@ startpr(enable)
printf("\tcouldn't start daemon\n");
else
printf("\tdaemon started\n");
+ seteuid(uid);
}
/*
@@ -890,12 +912,13 @@ stoppr()
SD = _PATH_DEFSPOOL;
if (cgetstr(bp, "lo", &LO) == -1)
LO = DEFLOCK;
- (void) sprintf(line, "%s/%s", SD, LO);
+ (void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
printf("%s:\n", printer);
/*
* Turn on the owner execute bit of the lock file to disable printing.
*/
+ seteuid(euid);
if (stat(line, &stbuf) >= 0) {
if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
printf("\tcannot disable printing\n");
@@ -913,6 +936,7 @@ stoppr()
}
} else
printf("\tcannot stat lock file\n");
+ seteuid(uid);
}
struct queue **queue;
@@ -954,10 +978,12 @@ topq(argc, argv)
LO = DEFLOCK;
printf("%s:\n", printer);
+ seteuid(euid);
if (chdir(SD) < 0) {
printf("\tcannot chdir to %s\n", SD);
- return;
+ goto out;
}
+ seteuid(uid);
nitems = getq(&queue);
if (nitems == 0)
return;
@@ -981,9 +1007,13 @@ topq(argc, argv)
* Turn on the public execute bit of the lock file to
* get lpd to rebuild the queue after the current job.
*/
+ seteuid(euid);
if (changed && stat(LO, &stbuf) >= 0)
(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
-}
+
+out:
+ seteuid(uid);
+}
/*
* Reposition the job by changing the modification time of
@@ -994,10 +1024,14 @@ touch(q)
struct queue *q;
{
struct timeval tvp[2];
+ int ret;
tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
tvp[0].tv_usec = tvp[1].tv_usec = 0;
- return(utimes(q->q_name, tvp));
+ seteuid(euid);
+ ret = utimes(q->q_name, tvp);
+ seteuid(uid);
+ return (ret);
}
/*
@@ -1054,7 +1088,10 @@ doarg(job)
* Process item consisting of owner's name (example: henry).
*/
for (qq = queue + nitems; --qq >= queue; ) {
- if ((fp = fopen((*qq)->q_name, "r")) == NULL)
+ seteuid(euid);
+ fp = fopen((*qq)->q_name, "r");
+ seteuid(uid);
+ if (fp == NULL)
continue;
while (getline(fp) > 0)
if (line[0] == 'P')
diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c
index 5135163..353d7cb 100644
--- a/usr.sbin/lpr/lpc/lpc.c
+++ b/usr.sbin/lpr/lpc/lpc.c
@@ -67,12 +67,15 @@ static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95";
* lpc -- line printer control program
*/
+#define MAX_CMDLINE 200
+#define MAX_MARGV 20
int fromatty;
-char cmdline[200];
+char cmdline[MAX_CMDLINE];
int margc;
-char *margv[20];
+char *margv[MAX_MARGV];
int top;
+uid_t uid, euid;
jmp_buf toplevel;
@@ -89,6 +92,9 @@ main(argc, argv)
{
register struct cmd *c;
+ euid = geteuid();
+ uid = getuid();
+ seteuid(uid);
name = argv[0];
openlog("lpd", 0, LOG_LPR);
@@ -144,7 +150,7 @@ cmdscanner(top)
printf("lpc> ");
fflush(stdout);
}
- if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
+ if (fgets(cmdline, MAX_CMDLINE, stdin) == 0)
quit(0, NULL);
if (cmdline[0] == 0 || cmdline[0] == '\n')
break;
@@ -204,9 +210,11 @@ makeargv()
{
register char *cp;
register char **argp = margv;
+ register int n = 0;
margc = 0;
- for (cp = cmdline; *cp;) {
+ for (cp = cmdline; *cp && (cp - cmdline) < sizeof(cmdline) &&
+ n < MAX_MARGV; n++) {
while (isspace(*cp))
cp++;
if (*cp == '\0')
diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c
index 65c8891..1a7448a 100644
--- a/usr.sbin/lpr/lpd/lpd.c
+++ b/usr.sbin/lpr/lpd/lpd.c
@@ -107,6 +107,8 @@ static void startup __P((void));
static void chkhost __P((struct sockaddr_in *));
static int ckqueue __P((char *));
+uid_t uid, euid;
+
int
main(argc, argv)
int argc;
@@ -118,9 +120,17 @@ main(argc, argv)
struct sockaddr_in sin, frominet;
int omask, lfd;
+ euid = geteuid(); /* these shouldn't be different */
+ uid = getuid();
options = 0;
gethostname(host, sizeof(host));
- name = argv[0];
+
+ name = "lpd";
+
+ if (euid != 0) {
+ fprintf(stderr,"lpd: must run as root\n");
+ exit(1);
+ }
while (--argc > 0) {
argv++;
@@ -532,11 +542,6 @@ chkhost(f)
int first = 1;
int good = 0;
- f->sin_port = ntohs(f->sin_port);
- if (f->sin_family != AF_INET || f->sin_port >= IPPORT_RESERVED ||
- f->sin_port == htons(20))
- fatal("Malformed from address");
-
/* Need real hostname for temporary filenames */
hp = gethostbyaddr((char *)&f->sin_addr,
sizeof(struct in_addr), f->sin_family);
diff --git a/usr.sbin/lpr/lpq/lpq.c b/usr.sbin/lpr/lpq/lpq.c
index 0e3ec33..56705bc 100644
--- a/usr.sbin/lpr/lpq/lpq.c
+++ b/usr.sbin/lpr/lpq/lpq.c
@@ -69,6 +69,8 @@ int requests; /* # of spool requests */
char *user[MAXUSERS]; /* users to process */
int users; /* # of users in user array */
+uid_t uid, euid;
+
static int ckqueue __P((char *));
void usage __P((void));
@@ -82,6 +84,9 @@ main(argc, argv)
int ch, aflag, lflag;
char *buf, *cp;
+ euid = geteuid();
+ uid = getuid();
+ seteuid(uid);
name = *argv;
if (gethostname(host, sizeof(host))) {
perror("lpq: gethostname");
diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c
index e362f03..4b66acc0e 100644
--- a/usr.sbin/lpr/lpr/lpr.c
+++ b/usr.sbin/lpr/lpr/lpr.c
@@ -45,7 +45,7 @@ static char copyright[] =
#ifndef lint
static char sccsid[] = "From: @(#)lpr.c 8.4 (Berkeley) 4/28/95"
- "\n$Id: lpr.c,v 1.15 1997/05/13 20:46:45 brian Exp $\n";
+ "\n$Id: lpr.c,v 1.16 1997/07/08 21:03:16 dima Exp $\n";
#endif /* not lint */
/*
@@ -113,6 +113,8 @@ static int nfile __P((char *));
static int test __P((char *));
static void usage __P((void));
+uid_t uid, euid;
+
int
main(argc, argv)
int argc;
@@ -125,6 +127,9 @@ main(argc, argv)
int c, i, f, errs;
struct stat stb;
+ euid = geteuid();
+ uid = getuid();
+ seteuid(uid);
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
signal(SIGHUP, cleanup);
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
@@ -281,7 +286,9 @@ main(argc, argv)
*/
mktemps();
tfd = nfile(tfname);
+ seteuid(euid);
(void) fchown(tfd, DU, -1); /* owned by daemon for protection */
+ seteuid(uid);
card('H', host);
card('P', person);
if (hdr) {
@@ -355,6 +362,7 @@ main(argc, argv)
/*
* Touch the control file to fix position in the queue.
*/
+ seteuid(euid);
if ((tfd = open(tfname, O_RDWR)) >= 0) {
char c;
@@ -373,6 +381,7 @@ main(argc, argv)
cleanup(0);
}
unlink(tfname);
+ seteuid(uid);
if (qflag) /* just q things up */
exit(0);
if (!startdaemon(printer))
@@ -380,6 +389,7 @@ main(argc, argv)
exit(0);
}
cleanup(0);
+ return (1);
/* NOTREACHED */
}
@@ -434,6 +444,7 @@ linked(file)
{
register char *cp;
static char buf[MAXPATHLEN];
+ register int ret;
if (*file != '/') {
if (getcwd(buf, sizeof(buf)) == NULL)
@@ -457,7 +468,10 @@ linked(file)
strncat(buf, file, sizeof(buf) - strlen(buf) - 1);
file = buf;
}
- return(symlink(file, dfname) ? NULL : file);
+ seteuid(euid);
+ ret = symlink(file, dfname);
+ seteuid(uid);
+ return(ret ? NULL : file);
}
/*
@@ -491,6 +505,7 @@ nfile(n)
register int f;
int oldumask = umask(0); /* should block signals */
+ seteuid(euid);
f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
(void) umask(oldumask);
if (f < 0) {
@@ -499,8 +514,9 @@ nfile(n)
}
if (fchown(f, userid, -1) < 0) {
printf("%s: cannot chown %s\n", name, n);
- cleanup(0);
+ cleanup(0); /* cleanup does exit */
}
+ seteuid(uid);
if (++n[inchar] > 'z') {
if (++n[inchar-2] == 't') {
printf("too many files - break up the job\n");
@@ -526,6 +542,7 @@ cleanup(signo)
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
i = inchar;
+ seteuid(euid);
if (tfname)
do
unlink(tfname);
@@ -580,9 +597,9 @@ test(file)
}
if (read(fd, &execb, sizeof(execb)) == sizeof(execb) &&
!N_BADMAG(execb)) {
- printf("%s: %s is an executable program", name, file);
- goto error1;
- }
+ printf("%s: %s is an executable program", name, file);
+ goto error1;
+ }
(void) close(fd);
if (rflag) {
if ((cp = rindex(file, '/')) == NULL) {
@@ -694,8 +711,10 @@ mktemps()
register int len, fd, n;
register char *cp;
char buf[BUFSIZ];
+ char *lmktemp();
(void) snprintf(buf, sizeof(buf), "%s/.seq", SD);
+ seteuid(euid);
if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) {
printf("%s: cannot create %s\n", name, buf);
exit(1);
@@ -704,6 +723,7 @@ mktemps()
printf("%s: cannot lock %s\n", name, buf);
exit(1);
}
+ seteuid(uid);
n = 0;
if ((len = read(fd, buf, sizeof(buf))) > 0) {
for (cp = buf; len--; ) {
diff --git a/usr.sbin/lpr/lprm/lprm.c b/usr.sbin/lpr/lprm/lprm.c
index 20c4ee7..df3a6cb 100644
--- a/usr.sbin/lpr/lprm/lprm.c
+++ b/usr.sbin/lpr/lprm/lprm.c
@@ -74,6 +74,7 @@ int requ[MAXREQUESTS]; /* job number of spool entries */
int requests; /* # of spool requests */
char *user[MAXUSERS]; /* users to process */
int users; /* # of users in user array */
+uid_t uid, euid; /* real and effective user id's */
static char luser[16]; /* buffer for person */
@@ -87,6 +88,9 @@ main(argc, argv)
register char *arg;
struct passwd *p;
+ uid = getuid();
+ euid = geteuid();
+ seteuid(uid); /* be safe */
name = argv[0];
gethostname(host, sizeof(host));
openlog("lpd", 0, LOG_LPR);
diff --git a/usr.sbin/lpr/pac/pac.c b/usr.sbin/lpr/pac/pac.c
index 692f005..609d407 100644
--- a/usr.sbin/lpr/pac/pac.c
+++ b/usr.sbin/lpr/pac/pac.c
@@ -71,6 +71,8 @@ static int sort; /* Sort by cost */
static char *sumfile; /* summary file */
static int summarize; /* Compress accounting file */
+uid_t uid, euid;
+
/*
* Grossness follows:
* Names to be accumulated are hashed into the following
@@ -106,6 +108,8 @@ main(argc, argv)
register FILE *acct;
register char *cp;
+ euid = geteuid(); /* these aren't used in pac(1) */
+ uid = getuid();
while (--argc) {
cp = *++argv;
if (*cp++ == '-') {
OpenPOWER on IntegriCloud