Module Name:    src
Committed By:   dholland
Date:           Sun Mar 13 00:32:09 UTC 2016

Modified Files:
        src/libexec/atrun: Makefile atrun.c
        src/usr.bin/at: Makefile at.c panic.c perm.c privs.h
Added Files:
        src/usr.bin/at: privs.c

Log Message:
Use functions instead of preprocessor abuse.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/libexec/atrun/Makefile
cvs rdiff -u -r1.21 -r1.22 src/libexec/atrun/atrun.c
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/at/Makefile
cvs rdiff -u -r1.30 -r1.31 src/usr.bin/at/at.c
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/at/panic.c
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/at/perm.c
cvs rdiff -u -r0 -r1.1 src/usr.bin/at/privs.c
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/at/privs.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/atrun/Makefile
diff -u src/libexec/atrun/Makefile:1.14 src/libexec/atrun/Makefile:1.15
--- src/libexec/atrun/Makefile:1.14	Tue Aug 16 10:35:03 2011
+++ src/libexec/atrun/Makefile	Sun Mar 13 00:32:09 2016
@@ -1,11 +1,15 @@
-#	$NetBSD: Makefile,v 1.14 2011/08/16 10:35:03 christos Exp $
+#	$NetBSD: Makefile,v 1.15 2016/03/13 00:32:09 dholland Exp $
 
 .include <bsd.own.mk>
 
 PROG=	atrun
+SRCS=	atrun.c
 BINDIR=	/usr/libexec
 MAN=	atrun.8
 
+.PATH.c: ${NETBSDSRCDIR}/usr.bin/at
+SRCS+=	privs.c
+
 CPPFLAGS+= -I${NETBSDSRCDIR}/usr.bin/at
 COPTS.atrun.c = -Wno-format-nonliteral
 

Index: src/libexec/atrun/atrun.c
diff -u src/libexec/atrun/atrun.c:1.21 src/libexec/atrun/atrun.c:1.22
--- src/libexec/atrun/atrun.c:1.21	Fri Sep 16 16:13:17 2011
+++ src/libexec/atrun/atrun.c	Sun Mar 13 00:32:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: atrun.c,v 1.21 2011/09/16 16:13:17 plunky Exp $	*/
+/*	$NetBSD: atrun.c,v 1.22 2016/03/13 00:32:09 dholland Exp $	*/
 
 /*
  *  atrun.c - run jobs queued by at; run with root privileges.
@@ -49,7 +49,6 @@
 
 /* Local headers */
 
-#define MAIN
 #include "privs.h"
 #include "pathnames.h"
 #include "atrun.h"
@@ -59,7 +58,7 @@
 #if 0
 static char rcsid[] = "$OpenBSD: atrun.c,v 1.7 1997/09/08 22:12:10 millert Exp $";
 #else
-__RCSID("$NetBSD: atrun.c,v 1.21 2011/09/16 16:13:17 plunky Exp $");
+__RCSID("$NetBSD: atrun.c,v 1.22 2016/03/13 00:32:09 dholland Exp $");
 #endif
 
 static int debug = 0;
@@ -108,6 +107,12 @@ perrx(const char *fmt, ...)
 	exit(EXIT_FAILURE);
 }
 
+__dead void
+privs_fail(const char *msg)
+{
+	perr("%s", msg);
+}
+
 static int
 write_string(int fd, const char *a)
 {
@@ -160,12 +165,12 @@ run_file(const char *filename, uid_t uid
 	gid_t ngid;
 	int serrno;
 
-	PRIV_START;
+	privs_enter();
 
 	if (chmod(filename, S_IRUSR) == -1)
 		perr("Cannot change file permissions to `%s'", filename);
 
-	PRIV_END;
+	privs_exit();
 
 	pid = fork();
 	if (pid == -1)
@@ -184,12 +189,12 @@ run_file(const char *filename, uid_t uid
 		perrx("Userid %lu not found - aborting job `%s'",
 		    (unsigned long)uid, filename);
 
-	PRIV_START;
+	privs_enter();
 
 	stream = fopen(filename, "r");
 	serrno = errno;
 
-	PRIV_END;
+	privs_exit();
 
 	if (stream == NULL) {
 		errno = serrno;
@@ -206,12 +211,12 @@ run_file(const char *filename, uid_t uid
 	if (fstat(fd_in, &buf) == -1)
 		perr("Error in fstat of input file descriptor");
 
-	PRIV_START;
+	privs_enter();
 
 	if (lstat(filename, &lbuf) == -1)
 		perr("Error in lstat of `%s'", filename);
 
-	PRIV_END;
+	privs_exit();
 
 	if (S_ISLNK(lbuf.st_mode))
 		perrx("Symbolic link encountered in job `%s' - aborting",
@@ -253,7 +258,7 @@ run_file(const char *filename, uid_t uid
 
 	(void)fclose(stream);
 
-	PRIV_START;
+	privs_enter();
 
 	if (chdir(_PATH_ATSPOOL) == -1)
 		perr("Cannot chdir to `%s'", _PATH_ATSPOOL);
@@ -267,7 +272,7 @@ run_file(const char *filename, uid_t uid
 		    O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) == -1)
 		perr("Cannot create output file `%s'", filename);
 
-	PRIV_END;
+	privs_exit();
 
 	write_string(fd_out, "To: ");
 	write_string(fd_out, mailname);
@@ -309,7 +314,7 @@ run_file(const char *filename, uid_t uid
 		(void)close(fd_in);
 		(void)close(fd_out);
 
-		PRIV_START;
+		privs_enter();
 
 		if (chdir(_PATH_ATJOBS) == -1)
 			perr("Cannot chdir to `%s'", _PATH_ATJOBS);
@@ -333,7 +338,7 @@ run_file(const char *filename, uid_t uid
 	 * Send mail.  Unlink the output file first, so it is deleted
 	 * after the run.
 	 */
-	PRIV_START;
+	privs_enter();
 
 	if (stat(filename, &buf) == -1)
 		perr("Error in stat of output file `%s'", filename);
@@ -342,12 +347,12 @@ run_file(const char *filename, uid_t uid
 
 	(void)unlink(filename);
 
-	PRIV_END;
+	privs_exit();
 
 	if ((buf.st_size != size) || send_mail) {
 		/* Fork off a child for sending mail */
 
-		PRIV_START;
+		privs_enter();
 
 		become_user(pentry, uid);
 
@@ -355,7 +360,7 @@ run_file(const char *filename, uid_t uid
 		    "-odi", "-oem", "-t", (char *) NULL);
 		perr("Exec failed for mail command `%s'", _PATH_SENDMAIL);
 
-		PRIV_END;
+		privs_exit();
 	}
 	exit(EXIT_SUCCESS);
 }
@@ -406,7 +411,7 @@ main(int argc, char *argv[])
 	 * We don't need root privileges all the time; running under uid
 	 * and gid nobody is fine except for privileged operations.
 	 */
-	RELINQUISH_PRIVS_ROOT(pwd->pw_uid, grp->gr_gid);
+	privs_relinquish_root(pwd->pw_uid, grp->gr_gid);
 
 	opterr = 0;
 	errno = 0;
@@ -433,7 +438,7 @@ main(int argc, char *argv[])
 		}
 	}
 
-	PRIV_START;
+	privs_enter();
 
 	if (chdir(_PATH_ATJOBS) == -1)
 		perr("Cannot change directory to `%s'", _PATH_ATJOBS);
@@ -453,7 +458,7 @@ main(int argc, char *argv[])
 	if ((spool = opendir(".")) == NULL)
 		perr("Cannot open `%s'", _PATH_ATJOBS);
 
-	PRIV_END;
+	privs_exit();
 
 	now = time(NULL);
 	run_batch = 0;
@@ -461,13 +466,13 @@ main(int argc, char *argv[])
 	batch_gid = (gid_t) -1;
 
 	while ((dirent = readdir(spool)) != NULL) {
-		PRIV_START;
+		privs_enter();
 
 		if (stat(dirent->d_name, &buf) == -1)
 			perr("Cannot stat `%s' in `%s'", dirent->d_name,
 			    _PATH_ATJOBS);
 
-		PRIV_END;
+		privs_exit();
 
 		/* We don't want directories */
 		if (!S_ISREG(buf.st_mode))
@@ -498,11 +503,11 @@ main(int argc, char *argv[])
 		/* Delete older files */
 		if ((run_time < now) && !(S_IXUSR & buf.st_mode) &&
 		    (S_IRUSR & buf.st_mode)) {
-			PRIV_START;
+			privs_enter();
 
 			(void)unlink(dirent->d_name);
 
-			PRIV_END;
+			privs_exit();
 		}
 	}
 

Index: src/usr.bin/at/Makefile
diff -u src/usr.bin/at/Makefile:1.11 src/usr.bin/at/Makefile:1.12
--- src/usr.bin/at/Makefile:1.11	Tue Apr 14 22:15:17 2009
+++ src/usr.bin/at/Makefile	Sun Mar 13 00:32:09 2016
@@ -1,9 +1,9 @@
-#	$NetBSD: Makefile,v 1.11 2009/04/14 22:15:17 lukem Exp $
+#	$NetBSD: Makefile,v 1.12 2016/03/13 00:32:09 dholland Exp $
 
 USE_FORT?=	yes	# setuid
 
 PROG=		at
-SRCS=		at.c panic.c parsetime.c perm.c stime.c
+SRCS=		at.c panic.c parsetime.c perm.c privs.c stime.c
 LINKS=		${BINDIR}/at ${BINDIR}/atq \
 		${BINDIR}/at ${BINDIR}/atrm \
 		${BINDIR}/at ${BINDIR}/batch

Index: src/usr.bin/at/at.c
diff -u src/usr.bin/at/at.c:1.30 src/usr.bin/at/at.c:1.31
--- src/usr.bin/at/at.c:1.30	Mon Aug 29 14:24:03 2011
+++ src/usr.bin/at/at.c	Sun Mar 13 00:32:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: at.c,v 1.30 2011/08/29 14:24:03 joerg Exp $	*/
+/*	$NetBSD: at.c,v 1.31 2016/03/13 00:32:09 dholland Exp $	*/
 
 /*
  *  at.c : Put file into atrun queue
@@ -57,7 +57,6 @@
 #include "perm.h"
 #include "pathnames.h"
 #include "stime.h"
-#define MAIN
 #include "privs.h"
 
 /* Macros */
@@ -72,7 +71,7 @@ enum { ATQ, ATRM, AT, BATCH, CAT };	/* w
 #if 0
 static char rcsid[] = "$OpenBSD: at.c,v 1.15 1998/06/03 16:20:26 deraadt Exp $";
 #else
-__RCSID("$NetBSD: at.c,v 1.30 2011/08/29 14:24:03 joerg Exp $");
+__RCSID("$NetBSD: at.c,v 1.31 2016/03/13 00:32:09 dholland Exp $");
 #endif
 #endif
 
@@ -108,9 +107,9 @@ sigc(int signo)
 
 	/* If a signal interrupts us, remove the spool file and exit. */
 	if (fcreated) {
-		PRIV_START;
+		privs_enter();
 		(void)unlink(atfile);
-		PRIV_END;
+		privs_exit();
 	}
 	(void)raise_default_signal(signo);
 	exit(EXIT_FAILURE);
@@ -207,7 +206,7 @@ writefile(time_t runtimer, unsigned char
 	 * to make sure we're alone when doing this.
 	 */
 
-	PRIV_START;
+	privs_enter();
 
 	if ((lockdes = open(_PATH_LOCKFILE, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR)) < 0)
 		perr("Cannot open lockfile " _PATH_LOCKFILE);
@@ -260,7 +259,7 @@ writefile(time_t runtimer, unsigned char
 	if (fchown(fd2, real_uid, real_gid) == -1)
 		perr("Cannot give away file");
 
-	PRIV_END;
+	privs_exit();
 
 	/*
 	 * We've successfully created the file; let's set the flag so it
@@ -402,7 +401,7 @@ writefile(time_t runtimer, unsigned char
 
 	(void)fclose(fp);
 
- 	PRIV_START;
+ 	privs_enter();
 
 	/*
 	 * Set the x bit so that we're ready to start executing
@@ -410,7 +409,7 @@ writefile(time_t runtimer, unsigned char
 	if (fchmod(fd2, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
 		perr("Cannot give away file");
 
-	PRIV_END;
+	privs_exit();
 
 	(void)close(fd2);
 	(void)fprintf(stderr,
@@ -436,7 +435,7 @@ list_jobs(void)
 	char timestr[TIMESIZE];
 	int first = 1;
 
-	PRIV_START;
+	privs_enter();
 
 	if (chdir(_PATH_ATJOBS) == -1)
 		perr("Cannot change to " _PATH_ATJOBS);
@@ -493,7 +492,7 @@ list_jobs(void)
 		    jobno);
 	}
 	(void)closedir(spool);
-	PRIV_END;
+	privs_exit();
 }
 
 static void
@@ -508,7 +507,7 @@ process_jobs(int argc, char **argv, int 
 	unsigned char queue;
 	int jobno;
 
-	PRIV_START;
+	privs_enter();
 
 	if (chdir(_PATH_ATJOBS) == -1)
 		perr("Cannot change to " _PATH_ATJOBS);
@@ -516,15 +515,15 @@ process_jobs(int argc, char **argv, int 
 	if ((spool = opendir(".")) == NULL)
 		perr("Cannot open " _PATH_ATJOBS);
 
-	PRIV_END;
+	privs_exit();
 
 	/* Loop over every file in the directory */
 	while((dirent = readdir(spool)) != NULL) {
 
-		PRIV_START;
+		privs_enter();
 		if (stat(dirent->d_name, &buf) == -1)
 			perr("Cannot stat in " _PATH_ATJOBS);
-		PRIV_END;
+		privs_exit();
 
 		if (sscanf(dirent->d_name, "%c%5x%8lx", &queue, &jobno, &ctm) !=3)
 			continue;
@@ -537,23 +536,23 @@ process_jobs(int argc, char **argv, int 
 
 				switch (what) {
 				case ATRM:
-					PRIV_START;
+					privs_enter();
 
 					if (unlink(dirent->d_name) == -1)
 						perr(dirent->d_name);
 
-					PRIV_END;
+					privs_exit();
 					break;
 
 				case CAT: {
 					FILE *fp;
 					int ch;
 
-					PRIV_START;
+					privs_enter();
 
 					fp = fopen(dirent->d_name, "r");
 
-					PRIV_END;
+					privs_exit();
 
 					if (!fp)
 						perr("Cannot open file");
@@ -593,7 +592,7 @@ main(int argc, char **argv)
 	int disp_version = 0;
 	time_t timer;
 
-	RELINQUISH_PRIVS;
+	privs_relinquish();
 
 	/* Eat any leading paths */
 	if ((pgm = strrchr(argv[0], '/')) == NULL)

Index: src/usr.bin/at/panic.c
diff -u src/usr.bin/at/panic.c:1.13 src/usr.bin/at/panic.c:1.14
--- src/usr.bin/at/panic.c:1.13	Sat Apr  5 16:26:57 2008
+++ src/usr.bin/at/panic.c	Sun Mar 13 00:32:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: panic.c,v 1.13 2008/04/05 16:26:57 christos Exp $	*/
+/*	$NetBSD: panic.c,v 1.14 2016/03/13 00:32:09 dholland Exp $	*/
 
 /*
  * panic.c - terminate fast in case of error
@@ -46,7 +46,7 @@
 #if 0
 static char rcsid[] = "$OpenBSD: panic.c,v 1.4 1997/03/01 23:40:09 millert Exp $";
 #else
-__RCSID("$NetBSD: panic.c,v 1.13 2008/04/05 16:26:57 christos Exp $");
+__RCSID("$NetBSD: panic.c,v 1.14 2016/03/13 00:32:09 dholland Exp $");
 #endif
 #endif
 
@@ -61,9 +61,9 @@ panic(const char *a)
 	 * Something fatal has happened, print error message and exit.
 	 */
 	if (fcreated) {
-		PRIV_START;
+		privs_enter();
 		(void)unlink(atfile);
-		PRIV_END;
+		privs_exit();
 	}
 	errx(EXIT_FAILURE, "%s", a);
 }
@@ -78,15 +78,22 @@ perr(const char *a)
 	 */
 	perror(a);
 	if (fcreated) {
-		PRIV_START;
+		privs_enter();
 		(void)unlink(atfile);
-		PRIV_END;
+		privs_exit();
 	}
 	exit(EXIT_FAILURE);
 }
 
 __dead
 void
+privs_fail(const char *msg)
+{
+	perr(msg);
+}
+
+__dead
+void
 usage(void)
 {
 

Index: src/usr.bin/at/perm.c
diff -u src/usr.bin/at/perm.c:1.3 src/usr.bin/at/perm.c:1.4
--- src/usr.bin/at/perm.c:1.3	Sat Apr  5 16:26:57 2008
+++ src/usr.bin/at/perm.c	Sun Mar 13 00:32:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: perm.c,v 1.3 2008/04/05 16:26:57 christos Exp $	*/
+/*	$NetBSD: perm.c,v 1.4 2016/03/13 00:32:09 dholland Exp $	*/
 
 /*
  * perm.c - check user permission for at(1)
@@ -51,7 +51,7 @@
 #if 0
 static char rcsid[] = "$OpenBSD: perm.c,v 1.1 1997/03/01 23:40:12 millert Exp $";
 #else
-__RCSID("$NetBSD: perm.c,v 1.3 2008/04/05 16:26:57 christos Exp $");
+__RCSID("$NetBSD: perm.c,v 1.4 2016/03/13 00:32:09 dholland Exp $");
 #endif
 #endif
 
@@ -96,20 +96,20 @@ check_permission(void)
 		exit(EXIT_FAILURE);
 	}
 
-	PRIV_START;
+	privs_enter();
 
 	fp = fopen(_PATH_AT_ALLOW, "r");
 
-	PRIV_END;
+	privs_exit();
 
 	if (fp != NULL) {
 		return check_for_user(fp, pentry->pw_name);
 	} else {
-		PRIV_START;
+		privs_enter();
 
 		fp = fopen(_PATH_AT_DENY, "r");
 
-		PRIV_END;
+		privs_exit();
 
 		if (fp != NULL)
 			return !check_for_user(fp, pentry->pw_name);

Index: src/usr.bin/at/privs.h
diff -u src/usr.bin/at/privs.h:1.8 src/usr.bin/at/privs.h:1.9
--- src/usr.bin/at/privs.h:1.8	Sat Apr  5 16:26:57 2008
+++ src/usr.bin/at/privs.h	Sun Mar 13 00:32:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: privs.h,v 1.8 2008/04/05 16:26:57 christos Exp $	*/
+/*	$NetBSD: privs.h,v 1.9 2016/03/13 00:32:09 dholland Exp $	*/
 
 /*
  *  privs.h - header for privileged operations
@@ -30,9 +30,8 @@
 #ifndef _PRIVS_H_
 #define _PRIVS_H_
 
-#include <unistd.h>
-
-/* Relinquish privileges temporarily for a setuid or setgid program
+/*
+ * Relinquish privileges temporarily for a setuid or setgid program
  * with the option of getting them back later.  This is done by
  * using POSIX saved user and groups ids.  Call RELINQUISH_PRIVS once
  * at the beginning of the main program.  This will cause all operations
@@ -57,44 +56,16 @@
  * to the real userid before calling any of them.
  */
 
-#ifndef MAIN
-extern
-#endif
-uid_t real_uid, effective_uid;
-
-#ifndef MAIN
-extern
-#endif
-gid_t real_gid, effective_gid;
-
-#define RELINQUISH_PRIVS do { \
-      real_uid = getuid(); \
-      effective_uid = geteuid(); \
-      real_gid = getgid(); \
-      effective_gid = getegid(); \
-      PRIV_END; \
-} while (/*CONSTCOND*/ 0)
-
-#define RELINQUISH_PRIVS_ROOT(a, b) do { \
-	real_uid = (a); \
-	effective_uid = geteuid(); \
-	real_gid = (b); \
-	effective_gid = getegid(); \
-	PRIV_END; \
-} while (/*CONSTCOND*/ 0)
-
-#define PRIV_START do { \
-	if (seteuid(effective_uid) == -1) \
-		perr("Cannot get user privs"); \
-	if (setegid(effective_gid) == -1) \
-		perr("Cannot get group privs"); \
-} while (/*CONSTCOND*/ 0)
-
-#define PRIV_END do { \
-	if (setegid(real_gid) == -1) \
-		perr("Cannot relinguish group privs"); \
-	if (seteuid(real_uid) == -1) \
-		perr("Cannot relinguish user privs"); \
-} while (/*CONSTCOND*/ 0)
+extern uid_t real_uid, effective_uid;
+extern gid_t real_gid, effective_gid;
+
+void privs_relinquish(void);
+void privs_relinquish_root(uid_t ruid, gid_t rgid);
+
+void privs_enter(void);
+void privs_exit(void);
+
+/* caller provides this */
+__dead void privs_fail(const char *msg);
 
 #endif /* _PRIV_H_ */

Added files:

Index: src/usr.bin/at/privs.c
diff -u /dev/null src/usr.bin/at/privs.c:1.1
--- /dev/null	Sun Mar 13 00:32:09 2016
+++ src/usr.bin/at/privs.c	Sun Mar 13 00:32:09 2016
@@ -0,0 +1,99 @@
+/*	$NetBSD: privs.c,v 1.1 2016/03/13 00:32:09 dholland Exp $	*/
+
+/*
+ *  privs.c - privileged operations
+ *  Copyright (C) 1993  Thomas Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author(s) may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * From: OpenBSD: privs.h,v 1.4 1997/03/01 23:40:12 millert Exp
+ */
+
+#include <unistd.h>
+
+#include "privs.h"
+
+/*
+ * Relinquish privileges temporarily for a setuid or setgid program
+ * with the option of getting them back later.  This is done by
+ * using POSIX saved user and groups ids.  Call RELINQUISH_PRIVS once
+ * at the beginning of the main program.  This will cause all operations
+ * to be executed with the real userid.  When you need the privileges
+ * of the setuid/setgid invocation, call PRIV_START; when you no longer
+ * need it, call PRIV_END.  Note that it is an error to call PRIV_START
+ * and not PRIV_END within the same function.
+ *
+ * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running
+ * as root, and you want to drop back the effective userid to a
+ * and the effective group id to b, with the option to get them back
+ * later.
+ *
+ * Problems: Do not use return between PRIV_START and PRIV_END; this
+ * will cause the program to continue running in an unprivileged
+ * state.
+ *
+ * It is NOT safe to call exec(), system() or popen() with a user-
+ * supplied program (i.e. without carefully checking PATH and any
+ * library load paths) with relinquished privileges; the called program
+ * can acquire them just as easily.  Set both effective and real userid
+ * to the real userid before calling any of them.
+ */
+
+uid_t real_uid, effective_uid;
+gid_t real_gid, effective_gid;
+
+void
+privs_enter(void)
+{
+	if (seteuid(effective_uid) == -1)
+		privs_fail("Cannot get user privs");
+	if (setegid(effective_gid) == -1)
+		privs_fail("Cannot get group privs");
+}
+
+void
+privs_exit(void)
+{
+	if (setegid(real_gid) == -1)
+		privs_fail("Cannot relinguish group privs");
+	if (seteuid(real_uid) == -1)
+		privs_fail("Cannot relinguish user privs");
+}
+
+void
+privs_relinquish(void)
+{
+	real_uid = getuid();
+	effective_uid = geteuid();
+	real_gid = getgid();
+	effective_gid = getegid();
+	privs_exit();
+}
+
+void
+privs_relinquish_root(uid_t ruid, gid_t rgid)
+{
+	real_uid = ruid;
+	real_gid = rgid;
+	effective_uid = geteuid();
+	effective_gid = getegid();
+	privs_exit();
+}

Reply via email to