Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Oct 2012 03:31:22 +0000 (UTC)
From:      Eitan Adler <eadler@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241852 - in head: sbin/ping sbin/ping6 usr.bin/at usr.sbin/lpr/common_source usr.sbin/lpr/lpc usr.sbin/lpr/lpd usr.sbin/lpr/lpq usr.sbin/lpr/lpr usr.sbin/lpr/lprm
Message-ID:  <201210220331.q9M3VMpT022258@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: eadler
Date: Mon Oct 22 03:31:22 2012
New Revision: 241852
URL: http://svn.freebsd.org/changeset/base/241852

Log:
  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

Modified:
  head/sbin/ping/ping.c
  head/sbin/ping6/ping6.c
  head/usr.bin/at/privs.h
  head/usr.sbin/lpr/common_source/common.c
  head/usr.sbin/lpr/common_source/displayq.c
  head/usr.sbin/lpr/common_source/lp.h
  head/usr.sbin/lpr/common_source/net.c
  head/usr.sbin/lpr/common_source/rmjob.c
  head/usr.sbin/lpr/common_source/startdaemon.c
  head/usr.sbin/lpr/lpc/cmds.c
  head/usr.sbin/lpr/lpc/lpc.c
  head/usr.sbin/lpr/lpc/movejobs.c
  head/usr.sbin/lpr/lpd/printjob.c
  head/usr.sbin/lpr/lpq/lpq.c
  head/usr.sbin/lpr/lpr/lpr.c
  head/usr.sbin/lpr/lprm/lprm.c

Modified: head/sbin/ping/ping.c
==============================================================================
--- head/sbin/ping/ping.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/sbin/ping/ping.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -255,7 +255,8 @@ main(int argc, char *const *argv)
 	s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 	sockerrno = errno;
 
-	setuid(getuid());
+	if (setuid(getuid()) != 0)
+		err(EX_NOPERM, "setuid() failed");
 	uid = getuid();
 
 	alarmtimeout = df = preload = tos = 0;

Modified: head/sbin/ping6/ping6.c
==============================================================================
--- head/sbin/ping6/ping6.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/sbin/ping6/ping6.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -702,8 +702,10 @@ main(int argc, char *argv[])
 	}
 
 	/* revoke root privilege */
-	seteuid(getuid());
-	setuid(getuid());
+	if (seteuid(getuid()) != 0)
+		err(1, "seteuid() failed");
+	if (setuid(getuid()) != 0)
+		err(1, "setuid() failed");
 
 	if ((options & F_FLOOD) && (options & F_INTERVAL))
 		errx(1, "-f and -i incompatible options");

Modified: head/usr.bin/at/privs.h
==============================================================================
--- head/usr.bin/at/privs.h	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.bin/at/privs.h	Mon Oct 22 03:31:22 2012	(r241852)
@@ -72,8 +72,8 @@ gid_t real_gid, effective_gid;
 	effective_uid = geteuid(); \
 	real_gid = getgid(); \
 	effective_gid = getegid(); \
-	seteuid(real_uid); \
-	setegid(real_gid); \
+	if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
+	if (setegid(real_gid) != 0) err(1, "setegid failed"); \
 }
 
 #define RELINQUISH_PRIVS_ROOT(a, b) { \
@@ -81,26 +81,26 @@ gid_t real_gid, effective_gid;
 	effective_uid = geteuid(); \
 	real_gid = (b); \
 	effective_gid = getegid(); \
-	setegid(real_gid); \
-	seteuid(real_uid); \
+	if (setegid(real_gid) != 0) err(1, "setegid failed"); \
+	if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
 }
 
 #define PRIV_START { \
-	seteuid(effective_uid); \
-	setegid(effective_gid); \
+	if (seteuid(effective_uid) != 0) err(1, "seteuid failed"); \
+	if (setegid(effective_gid) != 0) err(1, "setegid failed"); \
 }
 
 #define PRIV_END { \
-	setegid(real_gid); \
-	seteuid(real_uid); \
+	if (setegid(real_gid) != 0) err(1, "setegid failed"); \
+	if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \
 }
 
 #define REDUCE_PRIV(a, b) { \
 	PRIV_START \
 	effective_uid = (a); \
 	effective_gid = (b); \
-	setreuid((uid_t)-1, effective_uid); \
-	setregid((gid_t)-1, effective_gid); \
+	if (setreuid((uid_t)-1, effective_uid) != 0) err(1, "setreuid failed"); \
+	if (setregid((gid_t)-1, effective_gid) != 0) err(1, "setregid failed"); \
 	PRIV_END \
 }
 #endif

Modified: head/usr.sbin/lpr/common_source/common.c
==============================================================================
--- head/usr.sbin/lpr/common_source/common.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/common.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -125,14 +126,14 @@ getq(const struct printer *pp, struct jo
 	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 @@ getq(const struct printer *pp, struct jo
 	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 @@ getq(const struct printer *pp, struct jo
 
 errdone:
 	closedir(dirp);
-	seteuid(uid);
+	PRIV_END
 	return (-1);
 }
 
@@ -340,10 +341,10 @@ set_qstate(int action, const char *lfnam
 	 * 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 @@ set_qstate(int action, const char *lfnam
 	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 @@ set_qstate(int action, const char *lfnam
 		 * 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) {

Modified: head/usr.sbin/lpr/common_source/displayq.c
==============================================================================
--- head/usr.sbin/lpr/common_source/displayq.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/displayq.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -90,7 +91,7 @@ static const char  *head1 = "Total Size\
 
 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 @@ displayq(struct printer *pp, int format)
 	 * 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 @@ displayq(struct printer *pp, int format)
 	}
 
 	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 @@ displayq(struct printer *pp, int format)
 			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 @@ displayq(struct printer *pp, int format)
 				 */
 				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 @@ check_next:
  * 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 @@ inform(const struct printer *pp, char *c
 	 * 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 @@ dump(const char *nfile, const char *data
 	}
 	first = 0;
 
-	seteuid(euid);
+	PRIV_START
 	if (*datafile && !stat(datafile, &lbuf))
 		totsize += copies * lbuf.st_size;
-	seteuid(uid);
+	PRIV_END
 }
 
 /*

Modified: head/usr.sbin/lpr/common_source/lp.h
==============================================================================
--- head/usr.sbin/lpr/common_source/lp.h	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/lp.h	Mon Oct 22 03:31:22 2012	(r241852)
@@ -249,6 +249,17 @@ typedef enum { TR_SENDING, TR_RECVING, T
 #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

Modified: head/usr.sbin/lpr/common_source/net.c
==============================================================================
--- head/usr.sbin/lpr/common_source/net.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/net.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #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 @@ getport(const struct printer *pp, const 
 {
 	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 @@ getport(const struct printer *pp, const 
 	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 @@ getport(const struct printer *pp, const 
 	 */
 	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 @@ retry:
 		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 @@ checkremote(struct printer *pp)
 {
 	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 @@ checkremote(struct printer *pp)
 	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 @@ checkremote(struct printer *pp)
 	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;

Modified: head/usr.sbin/lpr/common_source/rmjob.c
==============================================================================
--- head/usr.sbin/lpr/common_source/rmjob.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/rmjob.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <signal.h>
 #include <stdio.h>
@@ -110,12 +111,12 @@ rmjob(const char *printer)
 		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 @@ rmjob(const char *printer)
 		 *  (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 @@ lockchk(struct printer *pp, char *slockf
 	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 @@ process(const struct printer *pp, char *
 
 	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 @@ do_unlink(char *file)
 
 	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 @@ chk(char *file)
 	/*
 	 * 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;

Modified: head/usr.sbin/lpr/common_source/startdaemon.c
==============================================================================
--- head/usr.sbin/lpr/common_source/startdaemon.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/common_source/startdaemon.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -74,9 +74,9 @@ startdaemon(const struct printer *pp)
 #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.");

Modified: head/usr.sbin/lpr/lpc/cmds.c
==============================================================================
--- head/usr.sbin/lpr/lpc/cmds.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpc/cmds.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 
 #include <signal.h>
 #include <fcntl.h>
+#include <err.h>
 #include <errno.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -288,10 +289,10 @@ kill_qtask(const char *lf)
 	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 @@ kill_qtask(const char *lf)
 		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 @@ upstat(struct printer *pp, const char *m
 
 	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 @@ clean_q(struct printer *pp)
 	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 @@ unlinkf(char *name)
 	 * 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 @@ unlinkf(char *name)
 	 * 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 @@ unlinkf(char *name)
 			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 @@ restart_q(struct printer *pp)
 	/* 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 @@ start_q(struct printer *pp)
 
 	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 @@ topq(int argc, char *argv[])
 	}
 	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 @@ topq(int argc, char *argv[])
 	 * 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 @@ touch(struct jobqueue *jq)
 
 	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 @@ doarg(char *job)
 	 * 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 @@ up_q(struct printer *pp)
 
 	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

Modified: head/usr.sbin/lpr/lpc/lpc.c
==============================================================================
--- head/usr.sbin/lpr/lpc/lpc.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpc/lpc.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -93,7 +93,7 @@ main(int argc, char *argv[])
 
 	euid = geteuid();
 	uid = getuid();
-	seteuid(uid);
+	PRIV_END
 	progname = argv[0];
 	openlog("lpd", 0, LOG_LPR);
 
@@ -405,9 +405,9 @@ setup_myprinter(char *pwanted, struct pr
 		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);

Modified: head/usr.sbin/lpr/lpc/movejobs.c
==============================================================================
--- head/usr.sbin/lpr/lpc/movejobs.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpc/movejobs.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
 
 #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_jqe(void *myinfo, struct jobqueue 
 	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)

Modified: head/usr.sbin/lpr/lpd/printjob.c
==============================================================================
--- head/usr.sbin/lpr/lpd/printjob.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpd/printjob.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #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 @@ printjob(struct printer *pp)
 		    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);
 

Modified: head/usr.sbin/lpr/lpq/lpq.c
==============================================================================
--- head/usr.sbin/lpr/lpq/lpq.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpq/lpq.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -88,7 +88,7 @@ main(int argc, char **argv)
 	printer = NULL;
 	euid = geteuid();
 	uid = getuid();
-	seteuid(uid);
+	PRIV_END
 	progname = *argv;
 	if (gethostname(local_host, sizeof(local_host)))
 		err(1, "gethostname");

Modified: head/usr.sbin/lpr/lpr/lpr.c
==============================================================================
--- head/usr.sbin/lpr/lpr/lpr.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lpr/lpr.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -145,7 +145,7 @@ main(int argc, char *argv[])
 	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)
@@ -326,10 +326,10 @@ main(int argc, char *argv[])
 	 */
 	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);
@@ -415,7 +415,7 @@ main(int argc, char *argv[])
 			 * 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
@@ -453,11 +453,11 @@ main(int argc, char *argv[])
 			 * 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;
 			/*
@@ -467,7 +467,7 @@ main(int argc, char *argv[])
 			 */
 			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++)
@@ -479,7 +479,7 @@ main(int argc, char *argv[])
 		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) {
@@ -498,7 +498,7 @@ main(int argc, char *argv[])
 		/*
 		 * Touch the control file to fix position in the queue.
 		 */
-		seteuid(euid);
+		PRIV_START
 		if ((tfd = open(tfname, O_RDWR)) >= 0) {
 			char touch_c;
 
@@ -518,7 +518,7 @@ main(int argc, char *argv[])
 			cleanup(0);
 		}
 		unlink(tfname);
-		seteuid(uid);
+		PRIV_END
 		if (qflag)		/* just q things up */
 			exit(0);
 		if (!startdaemon(pp))
@@ -604,9 +604,9 @@ linked(const char *file)
 		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);
 }
 
@@ -638,7 +638,7 @@ nfile(char *n)
 	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) {
@@ -649,7 +649,7 @@ nfile(char *n)
 		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");
@@ -674,7 +674,7 @@ cleanup(int signo __unused)
 	signal(SIGQUIT, SIG_IGN);
 	signal(SIGTERM, SIG_IGN);
 	i = inchar;
-	seteuid(euid);
+	PRIV_START
 	if (tfname)
 		do
 			unlink(tfname);
@@ -846,7 +846,7 @@ mktemps(const struct printer *pp)
 	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);
@@ -855,7 +855,7 @@ mktemps(const struct printer *pp)
 		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--; ) {

Modified: head/usr.sbin/lpr/lprm/lprm.c
==============================================================================
--- head/usr.sbin/lpr/lprm/lprm.c	Mon Oct 22 03:30:17 2012	(r241851)
+++ head/usr.sbin/lpr/lprm/lprm.c	Mon Oct 22 03:31:22 2012	(r241852)
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
 
 #include <syslog.h>
 #include <dirent.h>
+#include <err.h>
 #include <pwd.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -93,7 +94,7 @@ main(int argc, char *argv[])
 	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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210220331.q9M3VMpT022258>