summaryrefslogtreecommitdiffstats
path: root/usr.sbin/lpr/common_source
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1997-07-23 00:49:46 +0000
committerimp <imp@FreeBSD.org>1997-07-23 00:49:46 +0000
commitf080009db57e6a7b246a2ab15d8a73e4563931b4 (patch)
tree3f6c130b47ee18671302ddcfcae8cef66be97455 /usr.sbin/lpr/common_source
parent5d2b7fa5ede6cefc6d4c6f7df3987bea7b9149b8 (diff)
downloadFreeBSD-src-f080009db57e6a7b246a2ab15d8a73e4563931b4.zip
FreeBSD-src-f080009db57e6a7b246a2ab15d8a73e4563931b4.tar.gz
Use setuid/seteuid around dangerous operations. Also a few buffer
overflow patches that were "near" to where these operations are taking place. The buffer overflows are from OpenBSD. The setuid/seteuid patches are from NetBSD by way of OpenBSD (they changed them a little), at least from my read of the tree. This is the first of a series of OpenBSD lpr/et al merges. It (and them) should be merged back into 2.2 and/or 2.1 (if requested) branches when they have been shaken out in -current. Obtained from: OpenBSD
Diffstat (limited to 'usr.sbin/lpr/common_source')
-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
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");
OpenPOWER on IntegriCloud