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:
parent
018b991e1d
commit
12d7249e24
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=167356
@ -26,7 +26,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd August 30, 2001
|
.Dd March 9, 2007
|
||||||
.Dt DAEMON 8
|
.Dt DAEMON 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -35,6 +35,8 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl cf
|
.Op Fl cf
|
||||||
|
.Op Fl u Ar user
|
||||||
|
.Op Fl g Ar group
|
||||||
.Op Fl p Ar pidfile
|
.Op Fl p Ar pidfile
|
||||||
.Ar command arguments ...
|
.Ar command arguments ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -42,6 +44,7 @@ The
|
|||||||
.Nm
|
.Nm
|
||||||
utility detaches itself from the controlling terminal and
|
utility detaches itself from the controlling terminal and
|
||||||
executes the program specified by its arguments.
|
executes the program specified by its arguments.
|
||||||
|
Privileges may be lowered to specified user and/or group.
|
||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
@ -51,10 +54,14 @@ Change the current working directory to the root
|
|||||||
.It Fl f
|
.It Fl f
|
||||||
Redirect standard input, standard output and standard error to
|
Redirect standard input, standard output and standard error to
|
||||||
.Pa /dev/null .
|
.Pa /dev/null .
|
||||||
|
.It Fl g Ar group
|
||||||
|
Drop privileges to specified group.
|
||||||
.It Fl p Ar file
|
.It Fl p Ar file
|
||||||
Write the ID of the created process into the
|
Write the ID of the created process into the
|
||||||
.Ar file
|
.Ar file
|
||||||
using
|
using
|
||||||
|
.It Fl u Ar user
|
||||||
|
Drop privileges to specified user.
|
||||||
.Xr pidfile 3
|
.Xr pidfile 3
|
||||||
functionality.
|
functionality.
|
||||||
Note, that the file will be created shortly before the process is
|
Note, that the file will be created shortly before the process is
|
||||||
@ -77,6 +84,8 @@ standard error unless the
|
|||||||
.Fl f
|
.Fl f
|
||||||
flag is specified.
|
flag is specified.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
.Xr setregid 2 ,
|
||||||
|
.Xr setreuid 2 ,
|
||||||
.Xr daemon 3 ,
|
.Xr daemon 3 ,
|
||||||
.Xr exec 3 ,
|
.Xr exec 3 ,
|
||||||
.Xr pidfile 3 ,
|
.Xr pidfile 3 ,
|
||||||
|
@ -35,11 +35,14 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <libutil.h>
|
#include <libutil.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void restrict_process(const char *, const char *);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -47,12 +50,12 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct pidfh *pfh;
|
struct pidfh *pfh;
|
||||||
int ch, nochdir, noclose, errcode;
|
int ch, nochdir, noclose, errcode;
|
||||||
const char *pidfile;
|
const char *pidfile, *user, *group;
|
||||||
pid_t otherpid;
|
pid_t otherpid;
|
||||||
|
|
||||||
nochdir = noclose = 1;
|
nochdir = noclose = 1;
|
||||||
pidfile = NULL;
|
pidfile = user = group = NULL;
|
||||||
while ((ch = getopt(argc, argv, "-cfp:")) != -1) {
|
while ((ch = getopt(argc, argv, "-cfg:p:u:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'c':
|
case 'c':
|
||||||
nochdir = 0;
|
nochdir = 0;
|
||||||
@ -60,6 +63,12 @@ main(int argc, char *argv[])
|
|||||||
case 'f':
|
case 'f':
|
||||||
noclose = 0;
|
noclose = 0;
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
user = optarg;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
group = optarg;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pidfile = optarg;
|
pidfile = optarg;
|
||||||
break;
|
break;
|
||||||
@ -72,6 +81,14 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
usage();
|
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),
|
* Try to open the pidfile before calling daemon(3),
|
||||||
* to be able to report the error intelligently
|
* to be able to report the error intelligently
|
||||||
@ -108,10 +125,35 @@ main(int argc, char *argv[])
|
|||||||
errc(1, errcode, "%s", argv[0]);
|
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
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void)fprintf(stderr,
|
(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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user