Check the return error of set[ug]id. While this can never fail in the
current version of FreeBSD, this isn't guarenteed by the API. Custom security modules, or future implementations of the setuid and setgid may fail. PR: bin/172289 PR: bin/172290 PR: bin/172291 Submittud by: Erik Cederstrand <erik@cederstrand.dk> Discussed by: freebsd-security Approved by: cperciva MFC after: 1 week
This commit is contained in:
parent
10d17a3f08
commit
1d1d4a4727
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241852
@ -255,7 +255,8 @@ main(int argc, char *const *argv)
|
|||||||
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||||
sockerrno = errno;
|
sockerrno = errno;
|
||||||
|
|
||||||
setuid(getuid());
|
if (setuid(getuid()) != 0)
|
||||||
|
err(EX_NOPERM, "setuid() failed");
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
|
|
||||||
alarmtimeout = df = preload = tos = 0;
|
alarmtimeout = df = preload = tos = 0;
|
||||||
|
@ -702,8 +702,10 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* revoke root privilege */
|
/* revoke root privilege */
|
||||||
seteuid(getuid());
|
if (seteuid(getuid()) != 0)
|
||||||
setuid(getuid());
|
err(1, "seteuid() failed");
|
||||||
|
if (setuid(getuid()) != 0)
|
||||||
|
err(1, "setuid() failed");
|
||||||
|
|
||||||
if ((options & F_FLOOD) && (options & F_INTERVAL))
|
if ((options & F_FLOOD) && (options & F_INTERVAL))
|
||||||
errx(1, "-f and -i incompatible options");
|
errx(1, "-f and -i incompatible options");
|
||||||
|
@ -72,8 +72,8 @@ gid_t real_gid, effective_gid;
|
|||||||
effective_uid = geteuid(); \
|
effective_uid = geteuid(); \
|
||||||
real_gid = getgid(); \
|
real_gid = getgid(); \
|
||||||
effective_gid = getegid(); \
|
effective_gid = getegid(); \
|
||||||
seteuid(real_uid); \
|
if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
|
||||||
setegid(real_gid); \
|
if (setegid(real_gid) != 0) err(1, "setegid failed"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RELINQUISH_PRIVS_ROOT(a, b) { \
|
#define RELINQUISH_PRIVS_ROOT(a, b) { \
|
||||||
@ -81,26 +81,26 @@ gid_t real_gid, effective_gid;
|
|||||||
effective_uid = geteuid(); \
|
effective_uid = geteuid(); \
|
||||||
real_gid = (b); \
|
real_gid = (b); \
|
||||||
effective_gid = getegid(); \
|
effective_gid = getegid(); \
|
||||||
setegid(real_gid); \
|
if (setegid(real_gid) != 0) err(1, "setegid failed"); \
|
||||||
seteuid(real_uid); \
|
if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PRIV_START { \
|
#define PRIV_START { \
|
||||||
seteuid(effective_uid); \
|
if (seteuid(effective_uid) != 0) err(1, "seteuid failed"); \
|
||||||
setegid(effective_gid); \
|
if (setegid(effective_gid) != 0) err(1, "setegid failed"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PRIV_END { \
|
#define PRIV_END { \
|
||||||
setegid(real_gid); \
|
if (setegid(real_gid) != 0) err(1, "setegid failed"); \
|
||||||
seteuid(real_uid); \
|
if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REDUCE_PRIV(a, b) { \
|
#define REDUCE_PRIV(a, b) { \
|
||||||
PRIV_START \
|
PRIV_START \
|
||||||
effective_uid = (a); \
|
effective_uid = (a); \
|
||||||
effective_gid = (b); \
|
effective_gid = (b); \
|
||||||
setreuid((uid_t)-1, effective_uid); \
|
if (setreuid((uid_t)-1, effective_uid) != 0) err(1, "setreuid failed"); \
|
||||||
setregid((gid_t)-1, effective_gid); \
|
if (setregid((gid_t)-1, effective_gid) != 0) err(1, "setregid failed"); \
|
||||||
PRIV_END \
|
PRIV_END \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -125,14 +126,14 @@ getq(const struct printer *pp, struct jobqueue *(*namelist[]))
|
|||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
int statres;
|
int statres;
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((dirp = opendir(pp->spool_dir)) == NULL) {
|
if ((dirp = opendir(pp->spool_dir)) == NULL) {
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (fstat(dirfd(dirp), &stbuf) < 0)
|
if (fstat(dirfd(dirp), &stbuf) < 0)
|
||||||
goto errdone;
|
goto errdone;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate the array size by taking the size of the directory file
|
* Estimate the array size by taking the size of the directory file
|
||||||
@ -149,9 +150,9 @@ getq(const struct printer *pp, struct jobqueue *(*namelist[]))
|
|||||||
while ((d = readdir(dirp)) != NULL) {
|
while ((d = readdir(dirp)) != NULL) {
|
||||||
if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
|
if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
|
||||||
continue; /* daemon control files only */
|
continue; /* daemon control files only */
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
statres = stat(d->d_name, &stbuf);
|
statres = stat(d->d_name, &stbuf);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (statres < 0)
|
if (statres < 0)
|
||||||
continue; /* Doesn't exist */
|
continue; /* Doesn't exist */
|
||||||
entrysz = sizeof(struct jobqueue) - sizeof(q->job_cfname) +
|
entrysz = sizeof(struct jobqueue) - sizeof(q->job_cfname) +
|
||||||
@ -184,7 +185,7 @@ getq(const struct printer *pp, struct jobqueue *(*namelist[]))
|
|||||||
|
|
||||||
errdone:
|
errdone:
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +341,10 @@ set_qstate(int action, const char *lfname)
|
|||||||
* Find what the current access-bits are.
|
* Find what the current access-bits are.
|
||||||
*/
|
*/
|
||||||
memset(&stbuf, 0, sizeof(stbuf));
|
memset(&stbuf, 0, sizeof(stbuf));
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
statres = stat(lfname, &stbuf);
|
statres = stat(lfname, &stbuf);
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if ((statres < 0) && (errsav != ENOENT)) {
|
if ((statres < 0) && (errsav != ENOENT)) {
|
||||||
printf("\tcannot stat() lock file\n");
|
printf("\tcannot stat() lock file\n");
|
||||||
return (SQS_STATFAIL);
|
return (SQS_STATFAIL);
|
||||||
@ -402,10 +403,10 @@ set_qstate(int action, const char *lfname)
|
|||||||
res = 0;
|
res = 0;
|
||||||
if (statres >= 0) {
|
if (statres >= 0) {
|
||||||
/* The file already exists, so change the access. */
|
/* The file already exists, so change the access. */
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
chres = chmod(lfname, chgbits);
|
chres = chmod(lfname, chgbits);
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
res = SQS_CHGOK;
|
res = SQS_CHGOK;
|
||||||
if (chres < 0)
|
if (chres < 0)
|
||||||
res = SQS_CHGFAIL;
|
res = SQS_CHGFAIL;
|
||||||
@ -424,10 +425,10 @@ set_qstate(int action, const char *lfname)
|
|||||||
* all the read/write bits are set as desired.
|
* all the read/write bits are set as desired.
|
||||||
*/
|
*/
|
||||||
oldmask = umask(S_IWOTH);
|
oldmask = umask(S_IWOTH);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fd = open(lfname, O_WRONLY|O_CREAT, newbits);
|
fd = open(lfname, O_WRONLY|O_CREAT, newbits);
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
umask(oldmask);
|
umask(oldmask);
|
||||||
res = SQS_CREFAIL;
|
res = SQS_CREFAIL;
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -90,7 +91,7 @@ static const char *head1 = "Total Size\n";
|
|||||||
|
|
||||||
static void alarmhandler(int _signo);
|
static void alarmhandler(int _signo);
|
||||||
static void filtered_write(char *_obuffer, int _wlen, FILE *_wstream);
|
static void filtered_write(char *_obuffer, int _wlen, FILE *_wstream);
|
||||||
static void warn(const struct printer *_pp);
|
static void daemonwarn(const struct printer *_pp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display the current state of the queue. Format = 1 if long format.
|
* Display the current state of the queue. Format = 1 if long format.
|
||||||
@ -119,24 +120,24 @@ displayq(struct printer *pp, int format)
|
|||||||
* Print out local queue
|
* Print out local queue
|
||||||
* Find all the control files in the spooling directory
|
* Find all the control files in the spooling directory
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (chdir(pp->spool_dir) < 0)
|
if (chdir(pp->spool_dir) < 0)
|
||||||
fatal(pp, "cannot chdir to spooling directory: %s",
|
fatal(pp, "cannot chdir to spooling directory: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if ((nitems = getq(pp, &queue)) < 0)
|
if ((nitems = getq(pp, &queue)) < 0)
|
||||||
fatal(pp, "cannot examine spooling area\n");
|
fatal(pp, "cannot examine spooling area\n");
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = stat(pp->lock_file, &statb);
|
ret = stat(pp->lock_file, &statb);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
if (statb.st_mode & LFM_PRINT_DIS) {
|
if (statb.st_mode & LFM_PRINT_DIS) {
|
||||||
if (pp->remote)
|
if (pp->remote)
|
||||||
printf("%s: ", local_host);
|
printf("%s: ", local_host);
|
||||||
printf("Warning: %s is down: ", pp->printer);
|
printf("Warning: %s is down: ", pp->printer);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
|
fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
while ((i = read(fd, line, sizeof(line))) > 0)
|
while ((i = read(fd, line, sizeof(line))) > 0)
|
||||||
(void) fwrite(line, 1, i, stdout);
|
(void) fwrite(line, 1, i, stdout);
|
||||||
@ -153,11 +154,11 @@ displayq(struct printer *pp, int format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nitems) {
|
if (nitems) {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fp = fopen(pp->lock_file, "r");
|
fp = fopen(pp->lock_file, "r");
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
warn(pp);
|
daemonwarn(pp);
|
||||||
else {
|
else {
|
||||||
/* get daemon pid */
|
/* get daemon pid */
|
||||||
cp = current;
|
cp = current;
|
||||||
@ -171,12 +172,12 @@ displayq(struct printer *pp, int format)
|
|||||||
if (i <= 0) {
|
if (i <= 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
} else {
|
} else {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = kill(i, 0);
|
ret = kill(i, 0);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
warn(pp);
|
daemonwarn(pp);
|
||||||
} else {
|
} else {
|
||||||
/* read current file name */
|
/* read current file name */
|
||||||
cp = current;
|
cp = current;
|
||||||
@ -191,9 +192,9 @@ displayq(struct printer *pp, int format)
|
|||||||
*/
|
*/
|
||||||
if (pp->remote)
|
if (pp->remote)
|
||||||
printf("%s: ", local_host);
|
printf("%s: ", local_host);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
|
fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
while ((i = read(fd, line,
|
while ((i = read(fd, line,
|
||||||
sizeof(line))) > 0)
|
sizeof(line))) > 0)
|
||||||
@ -360,7 +361,7 @@ filtered_write(char *wbuffer, int wlen, FILE *wstream)
|
|||||||
* Print a warning message if there is no daemon present.
|
* Print a warning message if there is no daemon present.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
warn(const struct printer *pp)
|
daemonwarn(const struct printer *pp)
|
||||||
{
|
{
|
||||||
if (pp->remote)
|
if (pp->remote)
|
||||||
printf("%s: ", local_host);
|
printf("%s: ", local_host);
|
||||||
@ -391,10 +392,10 @@ inform(const struct printer *pp, char *cf)
|
|||||||
* There's a chance the control file has gone away
|
* There's a chance the control file has gone away
|
||||||
* in the meantime; if this is the case just keep going
|
* in the meantime; if this is the case just keep going
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((cfp = fopen(cf, "r")) == NULL)
|
if ((cfp = fopen(cf, "r")) == NULL)
|
||||||
return;
|
return;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
|
|
||||||
if (rank < 0)
|
if (rank < 0)
|
||||||
rank = 0;
|
rank = 0;
|
||||||
@ -578,10 +579,10 @@ dump(const char *nfile, const char *datafile, int copies)
|
|||||||
}
|
}
|
||||||
first = 0;
|
first = 0;
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (*datafile && !stat(datafile, &lbuf))
|
if (*datafile && !stat(datafile, &lbuf))
|
||||||
totsize += copies * lbuf.st_size;
|
totsize += copies * lbuf.st_size;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -249,6 +249,17 @@ typedef enum { TR_SENDING, TR_RECVING, TR_PRINTING } tr_sendrecv;
|
|||||||
#define CMD_SHOWQ_LONG '\4'
|
#define CMD_SHOWQ_LONG '\4'
|
||||||
#define CMD_RMJOB '\5'
|
#define CMD_RMJOB '\5'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* seteuid() macros.
|
||||||
|
*/
|
||||||
|
#define PRIV_START { \
|
||||||
|
if (seteuid(uid) != 0) err(1, "seteuid failed"); \
|
||||||
|
}
|
||||||
|
#define PRIV_END { \
|
||||||
|
if (seteuid(euid) != 0) err(1, "seteuid failed"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */
|
#include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <dirent.h> /* required for lp.h, not used here */
|
#include <dirent.h> /* required for lp.h, not used here */
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -91,7 +92,7 @@ getport(const struct printer *pp, const char *rhost, int rport)
|
|||||||
{
|
{
|
||||||
struct addrinfo hints, *res, *ai;
|
struct addrinfo hints, *res, *ai;
|
||||||
int s, timo = 1, lport = IPPORT_RESERVED - 1;
|
int s, timo = 1, lport = IPPORT_RESERVED - 1;
|
||||||
int err, refused = 0;
|
int error, refused = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the host address and port number to connect to.
|
* Get the host address and port number to connect to.
|
||||||
@ -102,10 +103,10 @@ getport(const struct printer *pp, const char *rhost, int rport)
|
|||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = 0;
|
hints.ai_protocol = 0;
|
||||||
err = getaddrinfo(rhost, (rport == 0 ? "printer" : NULL),
|
error = getaddrinfo(rhost, (rport == 0 ? "printer" : NULL),
|
||||||
&hints, &res);
|
&hints, &res);
|
||||||
if (err)
|
if (error)
|
||||||
fatal(pp, "%s\n", gai_strerror(err));
|
fatal(pp, "%s\n", gai_strerror(error));
|
||||||
if (rport != 0)
|
if (rport != 0)
|
||||||
((struct sockaddr_in *) res->ai_addr)->sin_port = htons(rport);
|
((struct sockaddr_in *) res->ai_addr)->sin_port = htons(rport);
|
||||||
|
|
||||||
@ -114,9 +115,9 @@ getport(const struct printer *pp, const char *rhost, int rport)
|
|||||||
*/
|
*/
|
||||||
ai = res;
|
ai = res;
|
||||||
retry:
|
retry:
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
s = rresvport_af(&lport, ai->ai_family);
|
s = rresvport_af(&lport, ai->ai_family);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
if (ai->ai_next) {
|
if (ai->ai_next) {
|
||||||
@ -135,9 +136,9 @@ getport(const struct printer *pp, const char *rhost, int rport)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
|
if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
err = errno;
|
error = errno;
|
||||||
(void) close(s);
|
(void) close(s);
|
||||||
errno = err;
|
errno = error;
|
||||||
/*
|
/*
|
||||||
* This used to decrement lport, but the current semantics
|
* This used to decrement lport, but the current semantics
|
||||||
* of rresvport do not provide such a function (in fact,
|
* of rresvport do not provide such a function (in fact,
|
||||||
@ -184,8 +185,8 @@ checkremote(struct printer *pp)
|
|||||||
{
|
{
|
||||||
char lclhost[MAXHOSTNAMELEN];
|
char lclhost[MAXHOSTNAMELEN];
|
||||||
struct addrinfo hints, *local_res, *remote_res, *lr, *rr;
|
struct addrinfo hints, *local_res, *remote_res, *lr, *rr;
|
||||||
char *err;
|
char *error;
|
||||||
int ncommonaddrs, error;
|
int ncommonaddrs, errno;
|
||||||
char h1[NI_MAXHOST], h2[NI_MAXHOST];
|
char h1[NI_MAXHOST], h2[NI_MAXHOST];
|
||||||
|
|
||||||
if (!pp->rp_matches_local) { /* Remote printer doesn't match local */
|
if (!pp->rp_matches_local) { /* Remote printer doesn't match local */
|
||||||
@ -205,11 +206,11 @@ checkremote(struct printer *pp)
|
|||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
if ((error = getaddrinfo(lclhost, NULL, &hints, &local_res)) != 0) {
|
if ((errno = getaddrinfo(lclhost, NULL, &hints, &local_res)) != 0) {
|
||||||
asprintf(&err, "unable to get official name "
|
asprintf(&error, "unable to get official name "
|
||||||
"for local machine %s: %s",
|
"for local machine %s: %s",
|
||||||
lclhost, gai_strerror(error));
|
lclhost, gai_strerror(errno));
|
||||||
return err;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the official name of RM */
|
/* get the official name of RM */
|
||||||
@ -217,13 +218,13 @@ checkremote(struct printer *pp)
|
|||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
if ((error = getaddrinfo(pp->remote_host, NULL,
|
if ((errno = getaddrinfo(pp->remote_host, NULL,
|
||||||
&hints, &remote_res)) != 0) {
|
&hints, &remote_res)) != 0) {
|
||||||
asprintf(&err, "unable to get address list for "
|
asprintf(&error, "unable to get address list for "
|
||||||
"remote machine %s: %s",
|
"remote machine %s: %s",
|
||||||
pp->remote_host, gai_strerror(error));
|
pp->remote_host, gai_strerror(errno));
|
||||||
freeaddrinfo(local_res);
|
freeaddrinfo(local_res);
|
||||||
return err;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ncommonaddrs = 0;
|
ncommonaddrs = 0;
|
||||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -110,12 +111,12 @@ rmjob(const char *printer)
|
|||||||
person = root;
|
person = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (chdir(pp->spool_dir) < 0)
|
if (chdir(pp->spool_dir) < 0)
|
||||||
fatal(pp, "cannot chdir to spool directory");
|
fatal(pp, "cannot chdir to spool directory");
|
||||||
if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
|
if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
|
||||||
fatal(pp, "cannot access spool directory");
|
fatal(pp, "cannot access spool directory");
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
|
|
||||||
if (nitems) {
|
if (nitems) {
|
||||||
/*
|
/*
|
||||||
@ -124,9 +125,9 @@ rmjob(const char *printer)
|
|||||||
* (after which we have to restart the daemon).
|
* (after which we have to restart the daemon).
|
||||||
*/
|
*/
|
||||||
if (lockchk(pp, pp->lock_file) && chk(current)) {
|
if (lockchk(pp, pp->lock_file) && chk(current)) {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
assassinated = kill(cur_daemon, SIGINT) == 0;
|
assassinated = kill(cur_daemon, SIGINT) == 0;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (!assassinated)
|
if (!assassinated)
|
||||||
fatal(pp, "cannot kill printer daemon");
|
fatal(pp, "cannot kill printer daemon");
|
||||||
}
|
}
|
||||||
@ -156,14 +157,14 @@ lockchk(struct printer *pp, char *slockf)
|
|||||||
register FILE *fp;
|
register FILE *fp;
|
||||||
register int i, n;
|
register int i, n;
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((fp = fopen(slockf, "r")) == NULL) {
|
if ((fp = fopen(slockf, "r")) == NULL) {
|
||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
fatal(pp, "%s: %s", slockf, strerror(errno));
|
fatal(pp, "%s: %s", slockf, strerror(errno));
|
||||||
else
|
else
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (!getline(fp)) {
|
if (!getline(fp)) {
|
||||||
(void) fclose(fp);
|
(void) fclose(fp);
|
||||||
return(0); /* no daemon present */
|
return(0); /* no daemon present */
|
||||||
@ -195,10 +196,10 @@ process(const struct printer *pp, char *file)
|
|||||||
|
|
||||||
if (!chk(file))
|
if (!chk(file))
|
||||||
return;
|
return;
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((cfp = fopen(file, "r")) == NULL)
|
if ((cfp = fopen(file, "r")) == NULL)
|
||||||
fatal(pp, "cannot open %s", file);
|
fatal(pp, "cannot open %s", file);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
while (getline(cfp)) {
|
while (getline(cfp)) {
|
||||||
switch (line[0]) {
|
switch (line[0]) {
|
||||||
case 'U': /* unlink associated files */
|
case 'U': /* unlink associated files */
|
||||||
@ -218,9 +219,9 @@ do_unlink(char *file)
|
|||||||
|
|
||||||
if (from_host != local_host)
|
if (from_host != local_host)
|
||||||
printf("%s: ", local_host);
|
printf("%s: ", local_host);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = unlink(file);
|
ret = unlink(file);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
printf(ret ? "cannot dequeue %s\n" : "%s dequeued\n", file);
|
printf(ret ? "cannot dequeue %s\n" : "%s dequeued\n", file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,10 +249,10 @@ chk(char *file)
|
|||||||
/*
|
/*
|
||||||
* get the owner's name from the control file.
|
* get the owner's name from the control file.
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((cfp = fopen(file, "r")) == NULL)
|
if ((cfp = fopen(file, "r")) == NULL)
|
||||||
return(0);
|
return(0);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
while (getline(cfp)) {
|
while (getline(cfp)) {
|
||||||
if (line[0] == 'P')
|
if (line[0] == 'P')
|
||||||
break;
|
break;
|
||||||
|
@ -74,9 +74,9 @@ startdaemon(const struct printer *pp)
|
|||||||
#ifndef SUN_LEN
|
#ifndef SUN_LEN
|
||||||
#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
|
#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
|
||||||
#endif
|
#endif
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
connectres = connect(s, (struct sockaddr *)&un, SUN_LEN(&un));
|
connectres = connect(s, (struct sockaddr *)&un, SUN_LEN(&un));
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (connectres < 0) {
|
if (connectres < 0) {
|
||||||
warn("Unable to connect to %s", _PATH_SOCKETNAME);
|
warn("Unable to connect to %s", _PATH_SOCKETNAME);
|
||||||
warnx("Check to see if the master 'lpd' process is running.");
|
warnx("Check to see if the master 'lpd' process is running.");
|
||||||
|
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -288,10 +289,10 @@ kill_qtask(const char *lf)
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
int errsav, killres, lockres, res;
|
int errsav, killres, lockres, res;
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fp = fopen(lf, "r");
|
fp = fopen(lf, "r");
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
res = KQT_NODAEMON;
|
res = KQT_NODAEMON;
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
/*
|
/*
|
||||||
@ -329,10 +330,10 @@ kill_qtask(const char *lf)
|
|||||||
goto killdone;
|
goto killdone;
|
||||||
}
|
}
|
||||||
|
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
killres = kill(pid, SIGTERM);
|
killres = kill(pid, SIGTERM);
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (killres == 0) {
|
if (killres == 0) {
|
||||||
res = KQT_KILLOK;
|
res = KQT_KILLOK;
|
||||||
printf("\tdaemon (pid %d) killed\n", pid);
|
printf("\tdaemon (pid %d) killed\n", pid);
|
||||||
@ -376,9 +377,9 @@ upstat(struct printer *pp, const char *msg, int notifyuser)
|
|||||||
|
|
||||||
status_file_name(pp, statfile, sizeof statfile);
|
status_file_name(pp, statfile, sizeof statfile);
|
||||||
umask(0);
|
umask(0);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fd = open(statfile, O_WRONLY|O_CREAT|O_EXLOCK, STAT_FILE_MODE);
|
fd = open(statfile, O_WRONLY|O_CREAT|O_EXLOCK, STAT_FILE_MODE);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("\tcannot create status file: %s\n", strerror(errno));
|
printf("\tcannot create status file: %s\n", strerror(errno));
|
||||||
return;
|
return;
|
||||||
@ -683,9 +684,9 @@ clean_q(struct printer *pp)
|
|||||||
linerem = sizeof(line) - (lp - line);
|
linerem = sizeof(line) - (lp - line);
|
||||||
|
|
||||||
cln_foundcore = 0;
|
cln_foundcore = 0;
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
nitems = scandir(pp->spool_dir, &queue, doselect, sortq);
|
nitems = scandir(pp->spool_dir, &queue, doselect, sortq);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (nitems < 0) {
|
if (nitems < 0) {
|
||||||
if (!didhead) {
|
if (!didhead) {
|
||||||
printf("%s:\n", pp->printer);
|
printf("%s:\n", pp->printer);
|
||||||
@ -795,9 +796,9 @@ unlinkf(char *name)
|
|||||||
* that case, we need to check the last-mod time of the symlink, and
|
* that case, we need to check the last-mod time of the symlink, and
|
||||||
* not the file that the symlink is pointed at.
|
* not the file that the symlink is pointed at.
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
res = lstat(name, &stbuf);
|
res = lstat(name, &stbuf);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
printf("\terror return from stat(%s):\n", name);
|
printf("\terror return from stat(%s):\n", name);
|
||||||
printf("\t %s\n", strerror(errno));
|
printf("\t %s\n", strerror(errno));
|
||||||
@ -819,9 +820,9 @@ unlinkf(char *name)
|
|||||||
* symlink before unlink-ing the file itself
|
* symlink before unlink-ing the file itself
|
||||||
*/
|
*/
|
||||||
if (S_ISLNK(stbuf.st_mode)) {
|
if (S_ISLNK(stbuf.st_mode)) {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
res = readlink(name, linkbuf, sizeof(linkbuf));
|
res = readlink(name, linkbuf, sizeof(linkbuf));
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
printf("\terror return from readlink(%s):\n", name);
|
printf("\terror return from readlink(%s):\n", name);
|
||||||
printf("\t %s\n", strerror(errno));
|
printf("\t %s\n", strerror(errno));
|
||||||
@ -841,9 +842,9 @@ unlinkf(char *name)
|
|||||||
printf("\t (which is a symlink to %s)\n", linkbuf);
|
printf("\t (which is a symlink to %s)\n", linkbuf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
res = unlink(name);
|
res = unlink(name);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
printf("\tcannot remove %s (!)\n", name);
|
printf("\tcannot remove %s (!)\n", name);
|
||||||
else
|
else
|
||||||
@ -983,9 +984,9 @@ restart_q(struct printer *pp)
|
|||||||
/* make sure the queue is set to print jobs */
|
/* make sure the queue is set to print jobs */
|
||||||
setres = set_qstate(SQS_STARTP, lf);
|
setres = set_qstate(SQS_STARTP, lf);
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
startok = startdaemon(pp);
|
startok = startdaemon(pp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (!startok)
|
if (!startok)
|
||||||
printf("\tcouldn't restart daemon\n");
|
printf("\tcouldn't restart daemon\n");
|
||||||
else
|
else
|
||||||
@ -1049,14 +1050,14 @@ start_q(struct printer *pp)
|
|||||||
|
|
||||||
setres = set_qstate(SQS_STARTP, lf);
|
setres = set_qstate(SQS_STARTP, lf);
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
startok = startdaemon(pp);
|
startok = startdaemon(pp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (!startok)
|
if (!startok)
|
||||||
printf("\tcouldn't start daemon\n");
|
printf("\tcouldn't start daemon\n");
|
||||||
else
|
else
|
||||||
printf("\tdaemon started\n");
|
printf("\tdaemon started\n");
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1178,12 +1179,12 @@ topq(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("%s:\n", pp->printer);
|
printf("%s:\n", pp->printer);
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (chdir(pp->spool_dir) < 0) {
|
if (chdir(pp->spool_dir) < 0) {
|
||||||
printf("\tcannot chdir to %s\n", pp->spool_dir);
|
printf("\tcannot chdir to %s\n", pp->spool_dir);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
nitems = getq(pp, &queue);
|
nitems = getq(pp, &queue);
|
||||||
if (nitems == 0)
|
if (nitems == 0)
|
||||||
return;
|
return;
|
||||||
@ -1207,12 +1208,12 @@ topq(int argc, char *argv[])
|
|||||||
* Turn on the public execute bit of the lock file to
|
* Turn on the public execute bit of the lock file to
|
||||||
* get lpd to rebuild the queue after the current job.
|
* get lpd to rebuild the queue after the current job.
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (changed && stat(pp->lock_file, &stbuf) >= 0)
|
if (changed && stat(pp->lock_file, &stbuf) >= 0)
|
||||||
(void) chmod(pp->lock_file, stbuf.st_mode | LFM_RESET_QUE);
|
(void) chmod(pp->lock_file, stbuf.st_mode | LFM_RESET_QUE);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1227,9 +1228,9 @@ touch(struct jobqueue *jq)
|
|||||||
|
|
||||||
tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
|
tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
|
||||||
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = utimes(jq->job_cfname, tvp);
|
ret = utimes(jq->job_cfname, tvp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,9 +1287,9 @@ doarg(char *job)
|
|||||||
* Process item consisting of owner's name (example: henry).
|
* Process item consisting of owner's name (example: henry).
|
||||||
*/
|
*/
|
||||||
for (qq = queue + nitems; --qq >= queue; ) {
|
for (qq = queue + nitems; --qq >= queue; ) {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
fp = fopen((*qq)->job_cfname, "r");
|
fp = fopen((*qq)->job_cfname, "r");
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
continue;
|
continue;
|
||||||
while (getline(fp) > 0)
|
while (getline(fp) > 0)
|
||||||
@ -1319,9 +1320,9 @@ up_q(struct printer *pp)
|
|||||||
|
|
||||||
setres = set_qstate(SQS_ENABLEQ+SQS_STARTP, lf);
|
setres = set_qstate(SQS_ENABLEQ+SQS_STARTP, lf);
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
startok = startdaemon(pp);
|
startok = startdaemon(pp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (!startok)
|
if (!startok)
|
||||||
printf("\tcouldn't start daemon\n");
|
printf("\tcouldn't start daemon\n");
|
||||||
else
|
else
|
||||||
|
@ -93,7 +93,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
openlog("lpd", 0, LOG_LPR);
|
openlog("lpd", 0, LOG_LPR);
|
||||||
|
|
||||||
@ -405,9 +405,9 @@ setup_myprinter(char *pwanted, struct printer *pp, int sump_opts)
|
|||||||
printf("%s:\n", pp->printer);
|
printf("%s:\n", pp->printer);
|
||||||
|
|
||||||
if (sump_opts & SUMP_CHDIR_SD) {
|
if (sump_opts & SUMP_CHDIR_SD) {
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
cdres = chdir(pp->spool_dir);
|
cdres = chdir(pp->spool_dir);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (cdres < 0) {
|
if (cdres < 0) {
|
||||||
printf("\tcannot chdir to %s\n", pp->spool_dir);
|
printf("\tcannot chdir to %s\n", pp->spool_dir);
|
||||||
free_printer(pp);
|
free_printer(pp);
|
||||||
|
@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h> /* just for MAXNAMLEN, for job_cfname in lp.h! */
|
#include <dirent.h> /* just for MAXNAMLEN, for job_cfname in lp.h! */
|
||||||
|
#include <err.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -147,9 +148,9 @@ touch_jqe(void *myinfo, struct jobqueue *jq, struct jobspec *jspec)
|
|||||||
touch_info = myinfo;
|
touch_info = myinfo;
|
||||||
tvp[0].tv_sec = tvp[1].tv_sec = ++touch_info->newtime;
|
tvp[0].tv_sec = tvp[1].tv_sec = ++touch_info->newtime;
|
||||||
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = utimes(jq->job_cfname, tvp);
|
ret = utimes(jq->job_cfname, tvp);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (jspec->matcheduser)
|
if (jspec->matcheduser)
|
||||||
|
@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -173,7 +174,7 @@ printjob(struct printer *pp)
|
|||||||
pp->log_file);
|
pp->log_file);
|
||||||
(void) open(_PATH_DEVNULL, O_WRONLY);
|
(void) open(_PATH_DEVNULL, O_WRONLY);
|
||||||
}
|
}
|
||||||
setgid(getegid());
|
if(setgid(getegid()) != 0) err(1, "setgid() failed");
|
||||||
printpid = getpid(); /* for use with lprm */
|
printpid = getpid(); /* for use with lprm */
|
||||||
setpgrp(0, printpid);
|
setpgrp(0, printpid);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ main(int argc, char **argv)
|
|||||||
printer = NULL;
|
printer = NULL;
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
progname = *argv;
|
progname = *argv;
|
||||||
if (gethostname(local_host, sizeof(local_host)))
|
if (gethostname(local_host, sizeof(local_host)))
|
||||||
err(1, "gethostname");
|
err(1, "gethostname");
|
||||||
|
@ -145,7 +145,7 @@ main(int argc, char *argv[])
|
|||||||
printer = NULL;
|
printer = NULL;
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
||||||
signal(SIGHUP, cleanup);
|
signal(SIGHUP, cleanup);
|
||||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
||||||
@ -326,10 +326,10 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
mktemps(pp);
|
mktemps(pp);
|
||||||
tfd = nfile(tfname);
|
tfd = nfile(tfname);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
(void) fchown(tfd, pp->daemon_user, -1);
|
(void) fchown(tfd, pp->daemon_user, -1);
|
||||||
/* owned by daemon for protection */
|
/* owned by daemon for protection */
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
card('H', local_host);
|
card('H', local_host);
|
||||||
card('P', lpr_username);
|
card('P', lpr_username);
|
||||||
card('C', class);
|
card('C', class);
|
||||||
@ -415,7 +415,7 @@ main(int argc, char *argv[])
|
|||||||
* can be very significant when running services like
|
* can be very significant when running services like
|
||||||
* samba, pcnfs, CAP, et al.
|
* samba, pcnfs, CAP, et al.
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
didlink = 0;
|
didlink = 0;
|
||||||
/*
|
/*
|
||||||
* There are several things to check to avoid any
|
* There are several things to check to avoid any
|
||||||
@ -453,11 +453,11 @@ main(int argc, char *argv[])
|
|||||||
* safe. Otherwise, abandon the move and fall back
|
* safe. Otherwise, abandon the move and fall back
|
||||||
* to the (usual) copy method.
|
* to the (usual) copy method.
|
||||||
*/
|
*/
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
ret = access(dfname, R_OK);
|
ret = access(dfname, R_OK);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = unlink(arg);
|
ret = unlink(arg);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto nohardlink;
|
goto nohardlink;
|
||||||
/*
|
/*
|
||||||
@ -467,7 +467,7 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
chown(dfname, pp->daemon_user, getegid());
|
chown(dfname, pp->daemon_user, getegid());
|
||||||
chmod(dfname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
chmod(dfname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (format == 'p')
|
if (format == 'p')
|
||||||
card('T', title ? title : arg);
|
card('T', title ? title : arg);
|
||||||
for (i = 0; i < ncopies; i++)
|
for (i = 0; i < ncopies; i++)
|
||||||
@ -479,7 +479,7 @@ main(int argc, char *argv[])
|
|||||||
nohardlink:
|
nohardlink:
|
||||||
if (didlink)
|
if (didlink)
|
||||||
unlink(dfname);
|
unlink(dfname);
|
||||||
seteuid(uid); /* restore old uid */
|
PRIV_END /* restore old uid */
|
||||||
} /* end: if (f) */
|
} /* end: if (f) */
|
||||||
|
|
||||||
if ((i = open(arg, O_RDONLY)) < 0) {
|
if ((i = open(arg, O_RDONLY)) < 0) {
|
||||||
@ -498,7 +498,7 @@ main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* Touch the control file to fix position in the queue.
|
* Touch the control file to fix position in the queue.
|
||||||
*/
|
*/
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((tfd = open(tfname, O_RDWR)) >= 0) {
|
if ((tfd = open(tfname, O_RDWR)) >= 0) {
|
||||||
char touch_c;
|
char touch_c;
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ main(int argc, char *argv[])
|
|||||||
cleanup(0);
|
cleanup(0);
|
||||||
}
|
}
|
||||||
unlink(tfname);
|
unlink(tfname);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (qflag) /* just q things up */
|
if (qflag) /* just q things up */
|
||||||
exit(0);
|
exit(0);
|
||||||
if (!startdaemon(pp))
|
if (!startdaemon(pp))
|
||||||
@ -604,9 +604,9 @@ linked(const char *file)
|
|||||||
strncat(buf, file, sizeof(buf) - strlen(buf) - 1);
|
strncat(buf, file, sizeof(buf) - strlen(buf) - 1);
|
||||||
file = buf;
|
file = buf;
|
||||||
}
|
}
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
ret = symlink(file, dfname);
|
ret = symlink(file, dfname);
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
return(ret ? NULL : file);
|
return(ret ? NULL : file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +638,7 @@ nfile(char *n)
|
|||||||
register int f;
|
register int f;
|
||||||
int oldumask = umask(0); /* should block signals */
|
int oldumask = umask(0); /* should block signals */
|
||||||
|
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
|
f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
|
||||||
(void) umask(oldumask);
|
(void) umask(oldumask);
|
||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
@ -649,7 +649,7 @@ nfile(char *n)
|
|||||||
printf("%s: cannot chown %s\n", progname, n);
|
printf("%s: cannot chown %s\n", progname, n);
|
||||||
cleanup(0); /* cleanup does exit */
|
cleanup(0); /* cleanup does exit */
|
||||||
}
|
}
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
if (++n[inchar] > 'z') {
|
if (++n[inchar] > 'z') {
|
||||||
if (++n[inchar-2] == 't') {
|
if (++n[inchar-2] == 't') {
|
||||||
printf("too many files - break up the job\n");
|
printf("too many files - break up the job\n");
|
||||||
@ -674,7 +674,7 @@ cleanup(int signo __unused)
|
|||||||
signal(SIGQUIT, SIG_IGN);
|
signal(SIGQUIT, SIG_IGN);
|
||||||
signal(SIGTERM, SIG_IGN);
|
signal(SIGTERM, SIG_IGN);
|
||||||
i = inchar;
|
i = inchar;
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if (tfname)
|
if (tfname)
|
||||||
do
|
do
|
||||||
unlink(tfname);
|
unlink(tfname);
|
||||||
@ -846,7 +846,7 @@ mktemps(const struct printer *pp)
|
|||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
(void) snprintf(buf, sizeof(buf), "%s/.seq", pp->spool_dir);
|
(void) snprintf(buf, sizeof(buf), "%s/.seq", pp->spool_dir);
|
||||||
seteuid(euid);
|
PRIV_START
|
||||||
if ((fd = open(buf, O_RDWR|O_CREAT, 0664)) < 0) {
|
if ((fd = open(buf, O_RDWR|O_CREAT, 0664)) < 0) {
|
||||||
printf("%s: cannot create %s\n", progname, buf);
|
printf("%s: cannot create %s\n", progname, buf);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -855,7 +855,7 @@ mktemps(const struct printer *pp)
|
|||||||
printf("%s: cannot lock %s\n", progname, buf);
|
printf("%s: cannot lock %s\n", progname, buf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
seteuid(uid);
|
PRIV_END
|
||||||
n = 0;
|
n = 0;
|
||||||
if ((len = read(fd, buf, sizeof(buf))) > 0) {
|
if ((len = read(fd, buf, sizeof(buf))) > 0) {
|
||||||
for (cp = buf; len--; ) {
|
for (cp = buf; len--; ) {
|
||||||
|
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -93,7 +94,7 @@ main(int argc, char *argv[])
|
|||||||
printer = NULL;
|
printer = NULL;
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
seteuid(uid); /* be safe */
|
PRIV_END /* be safe */
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
gethostname(local_host, sizeof(local_host));
|
gethostname(local_host, sizeof(local_host));
|
||||||
openlog("lpd", 0, LOG_LPR);
|
openlog("lpd", 0, LOG_LPR);
|
||||||
|
Loading…
Reference in New Issue
Block a user