bin/108523: [patch] daemon(8): support for dropping privileges

Dmitri Alenitchev dmitri at dworlds.ru
Mon Jan 29 18:40:17 UTC 2007


>Number:         108523
>Category:       bin
>Synopsis:       [patch] daemon(8): support for dropping privileges
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 29 18:40:15 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Dmitri Alenitchev
>Release:        FreeBSD 5.4-RELEASE i386
>Organization:
Digital Worlds J.S.C.
>Environment:
System: FreeBSD opay.ru 5.4-RELEASE FreeBSD 5.4-RELEASE #0: Sun May 8 10:21:06 UTC 2005 root at harlow.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386


	
>Description:
	support for dropping privileges to specified user and/or group
>How-To-Repeat:
	
>Fix:

	

--- freebsd-daemon.diff begins here ---
Index: daemon.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/daemon/daemon.8,v
retrieving revision 1.7
diff -u -r1.7 daemon.8
--- daemon.8	24 Aug 2005 17:24:39 -0000	1.7
+++ daemon.8	29 Jan 2007 08:46:53 -0000
@@ -35,13 +35,16 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl cf
+.Op Fl u Ar user
+.Op Fl g Ar group
 .Op Fl p Ar pidfile
 .Ar command arguments ...
 .Sh DESCRIPTION
 The
 .Nm
 utility detaches itself from the controlling terminal and
-executes the program specified by its arguments.
+executes the program specified by its arguments. Privileges can
+be lowered to specified user and/or group.
 .Pp
 The options are as follows:
 .Bl -tag -width indent
@@ -51,6 +54,10 @@
 .It Fl f
 Redirect standard input, standard output and standard error to
 .Pa /dev/null .
+.It Fl u Ar user
+Drop privileges to specified user.
+.It Fl g Ar group
+Drop privileges to specified group.
 .It Fl p Ar file
 Write the ID of the created process into the
 .Ar file
@@ -77,6 +84,8 @@
 .Fl f
 flag is specified.
 .Sh SEE ALSO
+.Xr setregid 2 ,
+.Xr setreuid 2 ,
 .Xr daemon 3 ,
 .Xr exec 3 ,
 .Xr pidfile 3 ,
Index: daemon.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/daemon/daemon.c,v
retrieving revision 1.4
diff -u -r1.4 daemon.c
--- daemon.c	24 Aug 2005 17:24:39 -0000	1.4
+++ daemon.c	29 Jan 2007 08:46:53 -0000
@@ -35,11 +35,14 @@
 
 #include <err.h>
 #include <errno.h>
+#include <pwd.h>
+#include <grp.h>
 #include <libutil.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
+static void restrict_process(const char *, const char *);
 static void usage(void);
 
 int
@@ -47,12 +50,12 @@
 {
 	struct pidfh *pfh;
 	int ch, nochdir, noclose, errcode;
-	const char *pidfile;
+	const char *pidfile, *user, *group;
 	pid_t otherpid;
 
 	nochdir = noclose = 1;
-	pidfile = NULL;
-	while ((ch = getopt(argc, argv, "-cfp:")) != -1) {
+	pidfile = user = group = NULL;
+	while ((ch = getopt(argc, argv, "-cfu:g:p:")) != -1) {
 		switch (ch) {
 		case 'c':
 			nochdir = 0;
@@ -60,6 +63,12 @@
 		case 'f':
 			noclose = 0;
 			break;
+		case 'u':
+			user = optarg;
+			break;
+		case 'g':
+			group = optarg;
+			break;
 		case 'p':
 			pidfile = optarg;
 			break;
@@ -72,6 +81,14 @@
 
 	if (argc == 0)
 		usage();
+
+	if (user || group) {
+		if (geteuid() != 0)
+			errx(1, "Only root user is allowed to chroot & "
+			    "change UID/GID");
+		restrict_process(user, group);	    
+	}
+
 	/*
 	 * Try to open the pidfile before calling daemon(3),
 	 * to be able to report the error intelligently
@@ -109,9 +126,32 @@
 }
 
 static void
+restrict_process(const char *user, const char *group)
+{
+	struct group *gr = NULL;
+	struct passwd *pw = NULL;
+	errno = 0;
+
+	if (group != NULL) {
+		if ((gr = getgrnam(group)) == NULL)
+			errx(1, "Group %s does not exist", group);
+		if (setregid(gr->gr_gid, gr->gr_gid) == -1)
+			err(1, "%s", group);
+	}
+
+	if (user != NULL) {
+		if ((pw = getpwnam(user)) == NULL)
+			errx(1, "User %s does not exist", user);
+		if (setreuid(pw->pw_uid, pw->pw_uid) == -1)
+			err(1, "%s", user);
+	}		
+}
+
+static void
 usage(void)
 {
 	(void)fprintf(stderr,
-	    "usage: daemon [-cf] [-p pidfile] command arguments ...\n");
+	    "usage: daemon [-cf] [-u user] [-g group] [-p pidfile] command "
+	    "arguments ...\n");
 	exit(1);
 }
--- freebsd-daemon.diff ends here ---


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


More information about the freebsd-bugs mailing list