misc/172291: lpr(1): Check return value of setuid() and friends

Erik Cederstrand erik at cederstrand.dk
Wed Oct 3 00:00:29 UTC 2012


>Number:         172291
>Category:       misc
>Synopsis:       lpr(1): Check return value of setuid() and friends
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 03 00:00:29 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Erik Cederstrand
>Release:        CURRENT
>Organization:
>Environment:
>Description:
Similar to bin/172289. lpr doesn't check the return value of seteuid(). This can lead to privilege escalation.
>How-To-Repeat:

>Fix:
lpr uses seteuid() to switch between root and user privileges. Use example from at(1) and redefine seteuid() calls as macros PRIV_START and PRIV_END, and add a check on the return value in the macro. Place this macro in common_source/lp.h

Including err.h causes two name clashes: a variable named "err" and a function named "warn". Rename these.


Patch attached with submission follows:

Index: lpd/printjob.c
===================================================================
--- lpd/printjob.c	(revision 240960)
+++ lpd/printjob.c	(working copy)
@@ -61,6 +61,7 @@
 #include <syslog.h>
 #include <fcntl.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -173,7 +174,7 @@
 		    pp->log_file);
 		(void) open(_PATH_DEVNULL, O_WRONLY);
 	}
-	setgid(getegid());
+	if(setgid(getegid()) != 0) err(1, "setgid() failed");
 	printpid = getpid();			/* for use with lprm */
 	setpgrp(0, printpid);
 
Index: lpq/lpq.c
===================================================================
--- lpq/lpq.c	(revision 240960)
+++ lpq/lpq.c	(working copy)
@@ -88,7 +88,7 @@
 	printer = NULL;
 	euid = geteuid();
 	uid = getuid();
-	seteuid(uid);
+	PRIV_END
 	progname = *argv;
 	if (gethostname(local_host, sizeof(local_host)))
 		err(1, "gethostname");
Index: lpr/lpr.c
===================================================================
--- lpr/lpr.c	(revision 240960)
+++ lpr/lpr.c	(working copy)
@@ -144,7 +144,7 @@
 	printer = NULL;
 	euid = geteuid();
 	uid = getuid();
-	seteuid(uid);
+	PRIV_END
 	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
 		signal(SIGHUP, cleanup);
 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
@@ -325,10 +325,10 @@
 	 */
 	mktemps(pp);
 	tfd = nfile(tfname);
-	seteuid(euid);
+	PRIV_START
 	(void) fchown(tfd, pp->daemon_user, -1);
 	/* owned by daemon for protection */
-	seteuid(uid);
+	PRIV_END
 	card('H', local_host);
 	card('P', lpr_username);
 	card('C', class);
@@ -414,7 +414,7 @@
 			 * can be very significant when running services like
 			 * samba, pcnfs, CAP, et al.
 			 */
-			seteuid(euid);
+			PRIV_START
 			didlink = 0;
 			/*
 			 * There are several things to check to avoid any
@@ -452,11 +452,11 @@
 			 * safe.  Otherwise, abandon the move and fall back
 			 * to the (usual) copy method.
 			 */
-			seteuid(uid);
+			PRIV_END
 			ret = access(dfname, R_OK);
 			if (ret == 0)
 				ret = unlink(arg);
-			seteuid(euid);
+			PRIV_START
 			if (ret != 0)
 				goto nohardlink;
 			/*
@@ -466,7 +466,7 @@
 			 */
 			chown(dfname, pp->daemon_user, getegid());
 			chmod(dfname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-			seteuid(uid);
+			PRIV_END
 			if (format == 'p')
 				card('T', title ? title : arg);
 			for (i = 0; i < ncopies; i++)
@@ -478,7 +478,7 @@
 		nohardlink:
 			if (didlink)
 				unlink(dfname);
-			seteuid(uid);           /* restore old uid */
+			PRIV_END           /* restore old uid */
 		} /* end: if (f) */
 
 		if ((i = open(arg, O_RDONLY)) < 0) {
@@ -497,7 +497,7 @@
 		/*
 		 * Touch the control file to fix position in the queue.
 		 */
-		seteuid(euid);
+		PRIV_START
 		if ((tfd = open(tfname, O_RDWR)) >= 0) {
 			char touch_c;
 
@@ -517,7 +517,7 @@
 			cleanup(0);
 		}
 		unlink(tfname);
-		seteuid(uid);
+		PRIV_END
 		if (qflag)		/* just q things up */
 			exit(0);
 		if (!startdaemon(pp))
@@ -603,9 +603,9 @@
 		strncat(buf, file, sizeof(buf) - strlen(buf) - 1);
 		file = buf;
 	}
-	seteuid(euid);
+	PRIV_START
 	ret = symlink(file, dfname);
-	seteuid(uid);
+	PRIV_END
 	return(ret ? NULL : file);
 }
 
@@ -637,7 +637,7 @@
 	register int f;
 	int oldumask = umask(0);		/* should block signals */
 
-	seteuid(euid);
+	PRIV_START
 	f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
 	(void) umask(oldumask);
 	if (f < 0) {
@@ -648,7 +648,7 @@
 		printf("%s: cannot chown %s\n", progname, n);
 		cleanup(0);	/* cleanup does exit */
 	}
-	seteuid(uid);
+	PRIV_END
 	if (++n[inchar] > 'z') {
 		if (++n[inchar-2] == 't') {
 			printf("too many files - break up the job\n");
@@ -673,7 +673,7 @@
 	signal(SIGQUIT, SIG_IGN);
 	signal(SIGTERM, SIG_IGN);
 	i = inchar;
-	seteuid(euid);
+	PRIV_START
 	if (tfname)
 		do
 			unlink(tfname);
@@ -845,7 +845,7 @@
 	char buf[BUFSIZ];
 
 	(void) snprintf(buf, sizeof(buf), "%s/.seq", pp->spool_dir);
-	seteuid(euid);
+	PRIV_START
 	if ((fd = open(buf, O_RDWR|O_CREAT, 0664)) < 0) {
 		printf("%s: cannot create %s\n", progname, buf);
 		exit(1);
@@ -854,7 +854,7 @@
 		printf("%s: cannot lock %s\n", progname, buf);
 		exit(1);
 	}
-	seteuid(uid);
+	PRIV_END
 	n = 0;
 	if ((len = read(fd, buf, sizeof(buf))) > 0) {
 		for (cp = buf; len--; ) {
Index: common_source/rmjob.c
===================================================================
--- common_source/rmjob.c	(revision 240960)
+++ common_source/rmjob.c	(working copy)
@@ -41,6 +41,7 @@
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <signal.h>
 #include <stdio.h>
@@ -110,12 +111,12 @@
 		person = root;
 	}
 
-	seteuid(euid);
+	PRIV_START
 	if (chdir(pp->spool_dir) < 0)
 		fatal(pp, "cannot chdir to spool directory");
 	if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
 		fatal(pp, "cannot access spool directory");
-	seteuid(uid);
+	PRIV_END
 
 	if (nitems) {
 		/*
@@ -124,9 +125,9 @@
 		 *  (after which we have to restart the daemon).
 		 */
 		if (lockchk(pp, pp->lock_file) && chk(current)) {
-			seteuid(euid);
+			PRIV_START
 			assassinated = kill(cur_daemon, SIGINT) == 0;
-			seteuid(uid);
+			PRIV_END
 			if (!assassinated)
 				fatal(pp, "cannot kill printer daemon");
 		}
@@ -156,14 +157,14 @@
 	register FILE *fp;
 	register int i, n;
 
-	seteuid(euid);
+	PRIV_START
 	if ((fp = fopen(slockf, "r")) == NULL) {
 		if (errno == EACCES)
 			fatal(pp, "%s: %s", slockf, strerror(errno));
 		else
 			return(0);
 	}
-	seteuid(uid);
+	PRIV_END
 	if (!getline(fp)) {
 		(void) fclose(fp);
 		return(0);		/* no daemon present */
@@ -195,10 +196,10 @@
 
 	if (!chk(file))
 		return;
-	seteuid(euid);
+	PRIV_START
 	if ((cfp = fopen(file, "r")) == NULL)
 		fatal(pp, "cannot open %s", file);
-	seteuid(uid);
+	PRIV_END
 	while (getline(cfp)) {
 		switch (line[0]) {
 		case 'U':  /* unlink associated files */
@@ -218,9 +219,9 @@
 
 	if (from_host != local_host)
 		printf("%s: ", local_host);
-	seteuid(euid);
+	PRIV_START
 	ret = unlink(file);
-	seteuid(uid);
+	PRIV_END
 	printf(ret ? "cannot dequeue %s\n" : "%s dequeued\n", file);
 }
 
@@ -248,10 +249,10 @@
 	/*
 	 * get the owner's name from the control file.
 	 */
-	seteuid(euid);
+	PRIV_START
 	if ((cfp = fopen(file, "r")) == NULL)
 		return(0);
-	seteuid(uid);
+	PRIV_END
 	while (getline(cfp)) {
 		if (line[0] == 'P')
 			break;
Index: common_source/lp.h
===================================================================
--- common_source/lp.h	(revision 240960)
+++ common_source/lp.h	(working copy)
@@ -249,6 +249,17 @@
 #define	CMD_SHOWQ_LONG	'\4'
 #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> */
 
 __BEGIN_DECLS
Index: common_source/startdaemon.c
===================================================================
--- common_source/startdaemon.c	(revision 240960)
+++ common_source/startdaemon.c	(working copy)
@@ -74,9 +74,9 @@
 #ifndef SUN_LEN
 #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
 #endif
-	seteuid(euid);
+	PRIV_START
 	connectres = connect(s, (struct sockaddr *)&un, SUN_LEN(&un));
-	seteuid(uid);
+	PRIV_END
 	if (connectres < 0) {
 		warn("Unable to connect to %s", _PATH_SOCKETNAME);
 		warnx("Check to see if the master 'lpd' process is running.");
Index: common_source/displayq.c
===================================================================
--- common_source/displayq.c	(revision 240960)
+++ common_source/displayq.c	(working copy)
@@ -41,6 +41,7 @@
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -90,7 +91,7 @@
 
 static void	alarmhandler(int _signo);
 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.
@@ -119,24 +120,24 @@
 	 * Print out local queue
 	 * Find all the control files in the spooling directory
 	 */
-	seteuid(euid);
+	PRIV_START
 	if (chdir(pp->spool_dir) < 0)
 		fatal(pp, "cannot chdir to spooling directory: %s",
 		      strerror(errno));
-	seteuid(uid);
+	PRIV_END
 	if ((nitems = getq(pp, &queue)) < 0)
 		fatal(pp, "cannot examine spooling area\n");
-	seteuid(euid);
+	PRIV_START
 	ret = stat(pp->lock_file, &statb);
-	seteuid(uid);
+	PRIV_END
 	if (ret >= 0) {
 		if (statb.st_mode & LFM_PRINT_DIS) {
 			if (pp->remote)
 				printf("%s: ", local_host);
 			printf("Warning: %s is down: ", pp->printer);
-			seteuid(euid);
+			PRIV_START
 			fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
-			seteuid(uid);
+			PRIV_END
 			if (fd >= 0) {
 				while ((i = read(fd, line, sizeof(line))) > 0)
 					(void) fwrite(line, 1, i, stdout);
@@ -153,11 +154,11 @@
 	}
 
 	if (nitems) {
-		seteuid(euid);
+		PRIV_START
 		fp = fopen(pp->lock_file, "r");
-		seteuid(uid);
+		PRIV_END
 		if (fp == NULL)
-			warn(pp);
+			daemonwarn(pp);
 		else {
 			/* get daemon pid */
 			cp = current;
@@ -171,12 +172,12 @@
 			if (i <= 0) {
 				ret = -1;
 			} else {
-				seteuid(euid);
+				PRIV_START
 				ret = kill(i, 0);
-				seteuid(uid);
+				PRIV_END
 			}
 			if (ret < 0) {
-				warn(pp);
+				daemonwarn(pp);
 			} else {
 				/* read current file name */
 				cp = current;
@@ -191,9 +192,9 @@
 				 */
 				if (pp->remote)
 					printf("%s: ", local_host);
-				seteuid(euid);
+				PRIV_START
 				fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
-				seteuid(uid);
+				PRIV_END
 				if (fd >= 0) {
 					while ((i = read(fd, line,
 							 sizeof(line))) > 0)
@@ -360,7 +361,7 @@
  * Print a warning message if there is no daemon present.
  */
 static void
-warn(const struct printer *pp)
+daemonwarn(const struct printer *pp)
 {
 	if (pp->remote)
 		printf("%s: ", local_host);
@@ -391,10 +392,10 @@
 	 * There's a chance the control file has gone away
 	 * in the meantime; if this is the case just keep going
 	 */
-	seteuid(euid);
+	PRIV_START
 	if ((cfp = fopen(cf, "r")) == NULL)
 		return;
-	seteuid(uid);
+	PRIV_END
 
 	if (rank < 0)
 		rank = 0;
@@ -578,10 +579,10 @@
 	}
 	first = 0;
 
-	seteuid(euid);
+	PRIV_START
 	if (*datafile && !stat(datafile, &lbuf))
 		totsize += copies * lbuf.st_size;
-	seteuid(uid);
+	PRIV_END
 }
 
 /*
Index: common_source/net.c
===================================================================
--- common_source/net.c	(revision 240960)
+++ common_source/net.c	(working copy)
@@ -52,6 +52,7 @@
 #include <netdb.h>
 
 #include <dirent.h>		/* required for lp.h, not used here */
+#include <err.h>
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -91,7 +92,7 @@
 {
 	struct addrinfo hints, *res, *ai;
 	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.
@@ -102,10 +103,10 @@
 	hints.ai_family = family;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_protocol = 0;
-	err = getaddrinfo(rhost, (rport == 0 ? "printer" : NULL),
+	error = getaddrinfo(rhost, (rport == 0 ? "printer" : NULL),
 			  &hints, &res);
-	if (err)
-		fatal(pp, "%s\n", gai_strerror(err));
+	if (error)
+		fatal(pp, "%s\n", gai_strerror(error));
 	if (rport != 0)
 		((struct sockaddr_in *) res->ai_addr)->sin_port = htons(rport);
 
@@ -114,9 +115,9 @@
 	 */
 	ai = res;
 retry:
-	seteuid(euid);
+	PRIV_START
 	s = rresvport_af(&lport, ai->ai_family);
-	seteuid(uid);
+	PRIV_END
 	if (s < 0) {
 		if (errno != EAGAIN) {
 			if (ai->ai_next) {
@@ -135,9 +136,9 @@
 		return(-1);
 	}
 	if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
-		err = errno;
+		error = errno;
 		(void) close(s);
-		errno = err;
+		errno = error;
 		/*
 		 * This used to decrement lport, but the current semantics
 		 * of rresvport do not provide such a function (in fact,
@@ -184,8 +185,8 @@
 {
 	char lclhost[MAXHOSTNAMELEN];
 	struct addrinfo hints, *local_res, *remote_res, *lr, *rr;
-	char *err;
-	int ncommonaddrs, error;
+	char *error;
+	int ncommonaddrs, errno;
 	char h1[NI_MAXHOST], h2[NI_MAXHOST];
 
 	if (!pp->rp_matches_local) { /* Remote printer doesn't match local */
@@ -205,11 +206,11 @@
 	hints.ai_family = family;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags = AI_PASSIVE;
-	if ((error = getaddrinfo(lclhost, NULL, &hints, &local_res)) != 0) {
-		asprintf(&err, "unable to get official name "
+	if ((errno = getaddrinfo(lclhost, NULL, &hints, &local_res)) != 0) {
+		asprintf(&error, "unable to get official name "
 			 "for local machine %s: %s",
-			 lclhost, gai_strerror(error));
-		return err;
+			 lclhost, gai_strerror(errno));
+		return error;
 	}
 
 	/* get the official name of RM */
@@ -217,13 +218,13 @@
 	hints.ai_family = family;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags = AI_PASSIVE;
-	if ((error = getaddrinfo(pp->remote_host, NULL,
+	if ((errno = getaddrinfo(pp->remote_host, NULL,
 				 &hints, &remote_res)) != 0) {
-		asprintf(&err, "unable to get address list for "
+		asprintf(&error, "unable to get address list for "
 			 "remote machine %s: %s",
-			 pp->remote_host, gai_strerror(error));
+			 pp->remote_host, gai_strerror(errno));
 		freeaddrinfo(local_res);
-		return err;
+		return error;
 	}
 
 	ncommonaddrs = 0;
Index: common_source/common.c
===================================================================
--- common_source/common.c	(revision 240960)
+++ common_source/common.c	(working copy)
@@ -52,6 +52,7 @@
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -125,14 +126,14 @@
 	DIR *dirp;
 	int statres;
 
-	seteuid(euid);
+	PRIV_START
 	if ((dirp = opendir(pp->spool_dir)) == NULL) {
-		seteuid(uid);
+		PRIV_END
 		return (-1);
 	}
 	if (fstat(dirfd(dirp), &stbuf) < 0)
 		goto errdone;
-	seteuid(uid);
+	PRIV_END
 
 	/*
 	 * Estimate the array size by taking the size of the directory file
@@ -149,9 +150,9 @@
 	while ((d = readdir(dirp)) != NULL) {
 		if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
 			continue;	/* daemon control files only */
-		seteuid(euid);
+		PRIV_START
 		statres = stat(d->d_name, &stbuf);
-		seteuid(uid);
+		PRIV_END
 		if (statres < 0)
 			continue;	/* Doesn't exist */
 		entrysz = sizeof(struct jobqueue) - sizeof(q->job_cfname) +
@@ -184,7 +185,7 @@
 
 errdone:
 	closedir(dirp);
-	seteuid(uid);
+	PRIV_END
 	return (-1);
 }
 
@@ -340,10 +341,10 @@
 	 * Find what the current access-bits are.
 	 */
 	memset(&stbuf, 0, sizeof(stbuf));
-	seteuid(euid);
+	PRIV_START
 	statres = stat(lfname, &stbuf);
 	errsav = errno;
-	seteuid(uid);
+	PRIV_END
 	if ((statres < 0) && (errsav != ENOENT)) {
 		printf("\tcannot stat() lock file\n");
 		return (SQS_STATFAIL);
@@ -402,10 +403,10 @@
 	res = 0;
 	if (statres >= 0) {
 		/* The file already exists, so change the access. */
-		seteuid(euid);
+		PRIV_START
 		chres = chmod(lfname, chgbits);
 		errsav = errno;
-		seteuid(uid);
+		PRIV_END
 		res = SQS_CHGOK;
 		if (chres < 0)
 			res = SQS_CHGFAIL;
@@ -424,10 +425,10 @@
 		 * all the read/write bits are set as desired.
 		 */
 		oldmask = umask(S_IWOTH);
-		seteuid(euid);
+		PRIV_START
 		fd = open(lfname, O_WRONLY|O_CREAT, newbits);
 		errsav = errno;
-		seteuid(uid);
+		PRIV_END
 		umask(oldmask);
 		res = SQS_CREFAIL;
 		if (fd >= 0) {
Index: lprm/lprm.c
===================================================================
--- lprm/lprm.c	(revision 240960)
+++ lprm/lprm.c	(working copy)
@@ -58,6 +58,7 @@
 
 #include <syslog.h>
 #include <dirent.h>
+#include <err.h>
 #include <pwd.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -93,7 +94,7 @@
 	printer = NULL;
 	uid = getuid();
 	euid = geteuid();
-	seteuid(uid);	/* be safe */
+	PRIV_END	/* be safe */
 	progname = argv[0];
 	gethostname(local_host, sizeof(local_host));
 	openlog("lpd", 0, LOG_LPR);
Index: lpc/lpc.c
===================================================================
--- lpc/lpc.c	(revision 240960)
+++ lpc/lpc.c	(working copy)
@@ -93,7 +93,7 @@
 
 	euid = geteuid();
 	uid = getuid();
-	seteuid(uid);
+	PRIV_END
 	progname = argv[0];
 	openlog("lpd", 0, LOG_LPR);
 
@@ -405,9 +405,9 @@
 		printf("%s:\n", pp->printer);
 
 	if (sump_opts & SUMP_CHDIR_SD) {
-		seteuid(euid);
+		PRIV_START
 		cdres = chdir(pp->spool_dir);
-		seteuid(uid);
+		PRIV_END
 		if (cdres < 0) {
 			printf("\tcannot chdir to %s\n", pp->spool_dir);
 			free_printer(pp);
Index: lpc/movejobs.c
===================================================================
--- lpc/movejobs.c	(revision 240960)
+++ lpc/movejobs.c	(working copy)
@@ -47,6 +47,7 @@
 
 #include <ctype.h>
 #include <dirent.h>	/* just for MAXNAMLEN, for job_cfname in lp.h! */
+#include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -147,9 +148,9 @@
 	touch_info = myinfo;
 	tvp[0].tv_sec = tvp[1].tv_sec = ++touch_info->newtime;
 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
-	seteuid(euid);
+	PRIV_START
 	ret = utimes(jq->job_cfname, tvp);
-	seteuid(uid);
+	PRIV_END
 
 	if (ret == 0) {
 		if (jspec->matcheduser)
Index: lpc/cmds.c
===================================================================
--- lpc/cmds.c	(revision 240960)
+++ lpc/cmds.c	(working copy)
@@ -54,6 +54,7 @@
 
 #include <signal.h>
 #include <fcntl.h>
+#include <err.h>
 #include <errno.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -288,10 +289,10 @@
 	pid_t pid;
 	int errsav, killres, lockres, res;
 
-	seteuid(euid);
+	PRIV_START
 	fp = fopen(lf, "r");
 	errsav = errno;
-	seteuid(uid);
+	PRIV_END
 	res = KQT_NODAEMON;
 	if (fp == NULL) {
 		/*
@@ -329,10 +330,10 @@
 		goto killdone;
 	}
 
-	seteuid(uid);
+	PRIV_END
 	killres = kill(pid, SIGTERM);
 	errsav = errno;
-	seteuid(uid);
+	PRIV_END
 	if (killres == 0) {
 		res = KQT_KILLOK;
 		printf("\tdaemon (pid %d) killed\n", pid);
@@ -376,9 +377,9 @@
 
 	status_file_name(pp, statfile, sizeof statfile);
 	umask(0);
-	seteuid(euid);
+	PRIV_START
 	fd = open(statfile, O_WRONLY|O_CREAT|O_EXLOCK, STAT_FILE_MODE);
-	seteuid(uid);
+	PRIV_END
 	if (fd < 0) {
 		printf("\tcannot create status file: %s\n", strerror(errno));
 		return;
@@ -683,9 +684,9 @@
 	linerem = sizeof(line) - (lp - line);
 
 	cln_foundcore = 0;
-	seteuid(euid);
+	PRIV_START
 	nitems = scandir(pp->spool_dir, &queue, doselect, sortq);
-	seteuid(uid);
+	PRIV_END
 	if (nitems < 0) {
 		if (!didhead) {
 			printf("%s:\n", pp->printer);
@@ -795,9 +796,9 @@
 	 * that case, we need to check the last-mod time of the symlink, and
 	 * not the file that the symlink is pointed at.
 	 */
-	seteuid(euid);
+	PRIV_START
 	res = lstat(name, &stbuf);
-	seteuid(uid);
+	PRIV_END
 	if (res < 0) {
 		printf("\terror return from stat(%s):\n", name);
 		printf("\t      %s\n", strerror(errno));
@@ -819,9 +820,9 @@
 	 * symlink before unlink-ing the file itself
 	 */
 	if (S_ISLNK(stbuf.st_mode)) {
-		seteuid(euid);
+		PRIV_START
 		res = readlink(name, linkbuf, sizeof(linkbuf));
-		seteuid(uid);
+		PRIV_END
 		if (res < 0) {
 			printf("\terror return from readlink(%s):\n", name);
 			printf("\t      %s\n", strerror(errno));
@@ -841,9 +842,9 @@
 			printf("\t    (which is a symlink to %s)\n", linkbuf);
 		}
 	} else {
-		seteuid(euid);
+		PRIV_START
 		res = unlink(name);
-		seteuid(uid);
+		PRIV_END
 		if (res < 0)
 			printf("\tcannot remove %s (!)\n", name);
 		else
@@ -983,9 +984,9 @@
 	/* make sure the queue is set to print jobs */
 	setres = set_qstate(SQS_STARTP, lf);
 
-	seteuid(euid);
+	PRIV_START
 	startok = startdaemon(pp);
-	seteuid(uid);
+	PRIV_END
 	if (!startok)
 		printf("\tcouldn't restart daemon\n");
 	else
@@ -1049,14 +1050,14 @@
 
 	setres = set_qstate(SQS_STARTP, lf);
 
-	seteuid(euid);
+	PRIV_START
 	startok = startdaemon(pp);
-	seteuid(uid);
+	PRIV_END
 	if (!startok)
 		printf("\tcouldn't start daemon\n");
 	else
 		printf("\tdaemon started\n");
-	seteuid(uid);
+	PRIV_END
 }
 
 /*
@@ -1178,12 +1179,12 @@
 	}
 	printf("%s:\n", pp->printer);
 
-	seteuid(euid);
+	PRIV_START
 	if (chdir(pp->spool_dir) < 0) {
 		printf("\tcannot chdir to %s\n", pp->spool_dir);
 		goto out;
 	}
-	seteuid(uid);
+	PRIV_END
 	nitems = getq(pp, &queue);
 	if (nitems == 0)
 		return;
@@ -1207,12 +1208,12 @@
 	 * Turn on the public execute bit of the lock file to
 	 * get lpd to rebuild the queue after the current job.
 	 */
-	seteuid(euid);
+	PRIV_START
 	if (changed && stat(pp->lock_file, &stbuf) >= 0)
 		(void) chmod(pp->lock_file, stbuf.st_mode | LFM_RESET_QUE);
 
 out:
-	seteuid(uid);
+	PRIV_END
 } 
 
 /*
@@ -1227,9 +1228,9 @@
 
 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
-	seteuid(euid);
+	PRIV_START
 	ret = utimes(jq->job_cfname, tvp);
-	seteuid(uid);
+	PRIV_END
 	return (ret);
 }
 
@@ -1286,9 +1287,9 @@
 	 * Process item consisting of owner's name (example: henry).
 	 */
 	for (qq = queue + nitems; --qq >= queue; ) {
-		seteuid(euid);
+		PRIV_START
 		fp = fopen((*qq)->job_cfname, "r");
-		seteuid(uid);
+		PRIV_END
 		if (fp == NULL)
 			continue;
 		while (getline(fp) > 0)
@@ -1319,9 +1320,9 @@
 
 	setres = set_qstate(SQS_ENABLEQ+SQS_STARTP, lf);
 
-	seteuid(euid);
+	PRIV_START
 	startok = startdaemon(pp);
-	seteuid(uid);
+	PRIV_END
 	if (!startok)
 		printf("\tcouldn't start daemon\n");
 	else

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list