Add support for dropping privileges to a specified user and/or group.

PR:		108523
Submitted by:	Dmitri Alenitchev <dmitri@dworlds.ru> (original version)
Reviewed by:	mpp (first reply to PR)
This commit is contained in:
Tom Rhodes 2007-03-09 09:33:19 +00:00
parent 018b991e1d
commit 12d7249e24
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=167356
2 changed files with 56 additions and 5 deletions

View File

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 30, 2001
.Dd March 9, 2007
.Dt DAEMON 8
.Os
.Sh NAME
@ -35,6 +35,8 @@
.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
@ -42,6 +44,7 @@ The
.Nm
utility detaches itself from the controlling terminal and
executes the program specified by its arguments.
Privileges may be lowered to specified user and/or group.
.Pp
The options are as follows:
.Bl -tag -width indent
@ -51,10 +54,14 @@ Change the current working directory to the root
.It Fl f
Redirect standard input, standard output and standard error to
.Pa /dev/null .
.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
using
.It Fl u Ar user
Drop privileges to specified user.
.Xr pidfile 3
functionality.
Note, that the file will be created shortly before the process is
@ -77,6 +84,8 @@ standard error unless the
.Fl f
flag is specified.
.Sh SEE ALSO
.Xr setregid 2 ,
.Xr setreuid 2 ,
.Xr daemon 3 ,
.Xr exec 3 ,
.Xr pidfile 3 ,

View File

@ -35,11 +35,14 @@ __FBSDID("$FreeBSD$");
#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 @@ main(int argc, char *argv[])
{
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, "-cfg:p:u:")) != -1) {
switch (ch) {
case 'c':
nochdir = 0;
@ -60,6 +63,12 @@ main(int argc, char *argv[])
case 'f':
noclose = 0;
break;
case 'u':
user = optarg;
break;
case 'g':
group = optarg;
break;
case 'p':
pidfile = optarg;
break;
@ -72,6 +81,14 @@ main(int argc, char *argv[])
if (argc == 0)
usage();
if (user || group) {
if (getuid() != 0)
errx(1, "only root user is allowed to chroot "
"and change UID/GID");
restrict_process(user, group);
}
/*
* Try to open the pidfile before calling daemon(3),
* to be able to report the error intelligently
@ -108,10 +125,35 @@ main(int argc, char *argv[])
errc(1, errcode, "%s", argv[0]);
}
static void
restrict_process(const char *user, const char *group)
{
struct group *gr = NULL;
struct passwd *pw = NULL;
errno = 0;
if (group != NULL) {
if (initgroups(user, gr->gr_gid) == -1)
errx(1, "User not in group list");
if ((gr = getgrnam(group)) == NULL)
errx(1, "Group %s does not exist", group);
if (setgid(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 (setuid(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] [-g group] [-p pidfile] [-u user] command "
"arguments ...\n");
exit(1);
}