1
0
Fork 0
mirror of https://github.com/pygos/init.git synced 2024-11-22 19:19:47 +01:00

usyslogd: chroot into log dir and drop privileges

Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
David Oberhollenzer 2018-08-19 11:07:17 +02:00
parent 61bc850984
commit 325f919847
3 changed files with 105 additions and 17 deletions

View file

@ -1,5 +1,5 @@
description "starting usyslogd" description "starting usyslogd"
exec usyslogd --rotate-replace --max-size 8192 exec usyslogd --chroot --rotate-replace --max-size 8192
type respawn limit 5 type respawn limit 5
target boot target boot
after vfs after vfs

View file

@ -29,9 +29,6 @@
#include "util.h" #include "util.h"
#define SYSLOG_PATH PREFIXPATH "/var/log"
static const enum_map_t levels[] = { static const enum_map_t levels[] = {
{ "emergency", 0 }, { "emergency", 0 },
{ "alert", 1 }, { "alert", 1 },
@ -204,18 +201,6 @@ static int file_backend_init(log_backend_t *backend, int flags,
{ {
log_backend_file_t *log = (log_backend_file_t *)backend; log_backend_file_t *log = (log_backend_file_t *)backend;
if (mkdir(SYSLOG_PATH, 0755)) {
if (errno != EEXIST) {
perror("mkdir " SYSLOG_PATH);
return -1;
}
}
if (chdir(SYSLOG_PATH)) {
perror("cd " SYSLOG_PATH);
return -1;
}
log->flags = flags; log->flags = flags;
log->maxsize = sizelimit; log->maxsize = sizelimit;
return 0; return 0;

View file

@ -25,6 +25,9 @@
#include <getopt.h> #include <getopt.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include "backend.h" #include "backend.h"
#include "proto.h" #include "proto.h"
@ -32,6 +35,9 @@
#define SYSLOG_SOCKET PREFIXPATH "/dev/log" #define SYSLOG_SOCKET PREFIXPATH "/dev/log"
#define SYSLOG_PATH PREFIXPATH "/var/log"
#define DEFAULT_USER "syslogd"
#define DEFAULT_GROUP "syslogd"
#define GPL_URL "https://gnu.org/licenses/gpl.html" #define GPL_URL "https://gnu.org/licenses/gpl.html"
@ -41,6 +47,9 @@ static const struct option long_opts[] = {
{ "version", no_argument, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
{ "rotate-replace", no_argument, NULL, 'r' }, { "rotate-replace", no_argument, NULL, 'r' },
{ "max-size", required_argument, NULL, 'm' }, { "max-size", required_argument, NULL, 'm' },
{ "user", required_argument, NULL, 'u' },
{ "group", required_argument, NULL, 'g' },
{ "chroot", required_argument, NULL, 'c' },
{ NULL, 0, NULL, 0 }, { NULL, 0, NULL, 0 },
}; };
@ -59,7 +68,12 @@ const char *usage_string =
" -h, --help Print this help text and exit\n" " -h, --help Print this help text and exit\n"
" -V, --version Print version information and exit\n" " -V, --version Print version information and exit\n"
" -r, --rotate-replace Replace old log files when doing log rotation.\n" " -r, --rotate-replace Replace old log files when doing log rotation.\n"
" -m, --max-size <size> Automatically rotate log files bigger than this.\n"; " -m, --max-size <size> Automatically rotate log files bigger than this.\n"
" -u, --user <name> Run the syslog daemon as this user. If not set,\n"
" try to use the user '" DEFAULT_USER "'.\n"
" -g, --group <name> Run the syslog daemon as this group. If not set,\n"
" try to use the group '" DEFAULT_GROUP "'.\n"
" -c, --chroot If set, do a chroot into the log file path.\n";
@ -67,6 +81,9 @@ static volatile sig_atomic_t syslog_run = 1;
static volatile sig_atomic_t syslog_rotate = 0; static volatile sig_atomic_t syslog_rotate = 0;
static int log_flags = 0; static int log_flags = 0;
static size_t max_size = 0; static size_t max_size = 0;
static uid_t uid = 0;
static gid_t gid = 0;
static bool dochroot = false;
@ -117,9 +134,17 @@ static int handle_data(int fd)
static void process_options(int argc, char **argv) static void process_options(int argc, char **argv)
{ {
struct passwd *pw = getpwnam(DEFAULT_USER);
struct group *grp = getgrnam(DEFAULT_GROUP);
char *end; char *end;
int i; int i;
if (pw != NULL)
uid = pw->pw_uid;
if (grp != NULL)
gid = grp->gr_gid;
for (;;) { for (;;) {
i = getopt_long(argc, argv, short_opts, long_opts, NULL); i = getopt_long(argc, argv, short_opts, long_opts, NULL);
if (i == -1) if (i == -1)
@ -138,6 +163,28 @@ static void process_options(int argc, char **argv)
goto fail; goto fail;
} }
break; break;
case 'u':
pw = getpwnam(optarg);
if (pw == NULL) {
fprintf(stderr, "Cannot get UID for user %s\n",
optarg);
goto fail;
}
uid = pw->pw_uid;
break;
case 'g':
grp = getgrnam(optarg);
if (grp == NULL) {
fprintf(stderr,
"Cannot get GID for group %s\n",
optarg);
goto fail;
}
gid = grp->gr_gid;
break;
case 'c':
dochroot = true;
break;
case 'h': case 'h':
fputs(usage_string, stdout); fputs(usage_string, stdout);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -154,6 +201,51 @@ fail:
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static int chroot_setup(void)
{
if (mkdir(SYSLOG_PATH, 0750)) {
if (errno != EEXIST) {
perror("mkdir " SYSLOG_PATH);
return -1;
}
}
if (uid > 0 && gid > 0 && chown(SYSLOG_PATH, uid, gid) != 0) {
perror("chown " SYSLOG_PATH);
return -1;
}
if (chmod(SYSLOG_PATH, 0750)) {
perror("chmod " SYSLOG_PATH);
return -1;
}
if (chdir(SYSLOG_PATH)) {
perror("cd " SYSLOG_PATH);
return -1;
}
if (dochroot && chroot(SYSLOG_PATH) != 0) {
perror("chroot " SYSLOG_PATH);
return -1;
}
return 0;
}
static int user_setup(void)
{
if (gid > 0 && setresgid(gid, gid, gid) != 0) {
perror("setgid");
return -1;
}
if (uid > 0 && setresuid(uid, uid, uid) != 0) {
perror("setuid");
return -1;
}
return 0;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int sfd, status = EXIT_FAILURE; int sfd, status = EXIT_FAILURE;
@ -166,6 +258,17 @@ int main(int argc, char **argv)
if (sfd < 0) if (sfd < 0)
return EXIT_FAILURE; return EXIT_FAILURE;
if (uid > 0 && gid > 0 && chown(SYSLOG_SOCKET, uid, gid) != 0) {
perror("chown " SYSLOG_SOCKET);
return -1;
}
if (chroot_setup())
return EXIT_FAILURE;
if (user_setup())
return EXIT_FAILURE;
if (logmgr->init(logmgr, log_flags, max_size)) if (logmgr->init(logmgr, log_flags, max_size))
goto out; goto out;