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
This commit is contained in:
parent
b1ba015c25
commit
360d4ad5ab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=27618
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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--; ) {
|
||||
|
@ -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);
|
||||
|
@ -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++ == '-') {
|
||||
|
Loading…
Reference in New Issue
Block a user