Permalink
Browse files

Add command line and configuration option to set umask

Issue #1048 identified that files created by keepalived are created
with mode 0666. This commit changes the default to 0644, and also
allows the umask to be specified in the configuration or as a command
line option.

Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
  • Loading branch information...
pqarmitage committed Oct 31, 2018
1 parent 2d48d8c commit c6247a9ef2c7b33244ab1d3aa5d629ec49f0a067
@@ -529,6 +529,10 @@ global_defs { # Block identification
rs_init_notifies # Send notifies at startup for real servers that are starting up
no_checker_emails # Don't send an email every time a real server checker changes state;
# only send email when a real server is added or removed
umask [NUMBER|BITS] # The umask to use for creating files. The number can be specified in hex, octal
# or decimal. BITS are I{R|W|X}{USR|GRP|OTH}, e.g. IRGRP, separated by '|'s.
# The default umask is IWGRP | IWOTH. This option cannot override the
# command-line option.
}
net_namespace NAME # Set the network namespace to run in
@@ -499,6 +499,12 @@ and
# Don't send an email every time a real server checker changes state;
# only send email when a real server is added or removed
\fBno_checker_emails\fR
# The umask to use for creating files. The number can be specified in hex, octal
# or decimal. BITS are I{R|W|X}{USR|GRP|OTH}, e.g. IRGRP, separated by '|'s.
# The default umask is IWGRP | IWOTH. This option cannot override the
# command-line option.
\fBumask \fR[NUMBER|BITS]
}
.fi
.SH Static track groups
@@ -34,6 +34,7 @@ keepalived \- load\-balancing and high\-availability service
[\fB\-i\fP|\fB\-\-config-id\fP id]
[\fB\-x\fP|\fB\-\-snmp\fP]
[\fB\-A\fP|\fB\-\-snmp-agent-socket\fP=FILE]
[\fB\-u\fP|\fB\-\-umask\fP=NUMBER]
[\fB\-m\fP|\fB\-\-core\-dump\fP]
[\fB\-M\fP|\fB\-\-core\-dump\-pattern\fP[=PATTERN]]
[\fB\-\-signum\fP=SIGFUNC]
@@ -158,6 +159,9 @@ Enable the SNMP subsystem.
\fB -A, --snmp-agent-socket\fP=FILE
Use the specified socket for connection to SNMP master agent.
.TP
\fB -u, --umask\fP=NUMBER
The umask specified in the usual numeric way - see man umask(2)
.TP
\fB -m, --core-dump\fP
Override the RLIMIT_CORE hard and soft limits to enable keepalived to
produce a coredump in the event of a segfault or other failure.
@@ -571,5 +571,6 @@ dump_global_data(FILE *fp, data_t * data)
if (buf[0])
conf_write(fp, "%s", buf);
conf_write(fp, " rx_bufs_multiples = %u", global_data->vrrp_rx_bufs_multiples);
conf_write(fp, " umask = 0%o", global_data->umask);
#endif
}
@@ -35,6 +35,8 @@
#include <sched.h>
#endif
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WITH_SNMP_
#include "snmp.h"
@@ -1341,6 +1343,76 @@ no_checker_emails_handler(vector_t *strvec)
}
#endif
static void
umask_handler(vector_t *strvec)
{
long umask_long;
mode_t umask_val = 0;
char *mask = strvec_slot(strvec, 1);
char *endptr;
unsigned i;
char *p;
if (umask_cmdline) {
log_message(LOG_INFO, "umask command line option specified, ignoring config option");
return;
}
if (isdigit(mask[0])) {
if (vector_size(strvec) != 2) {
report_config_error(CONFIG_GENERAL_ERROR, "%s parameter(s) to umask option", vector_size(strvec) == 1 ? "Missing" : "Extra");
return;
}
umask_long = strtol(mask, &endptr, 0);
if (*endptr || umask_long < 0 || umask_long & ~0777L) {
report_config_error(CONFIG_GENERAL_ERROR, "invalid umask value %s", mask);
return;
}
umask_val = umask_long & 0777;
}
else {
bool need_or = false;
for (i = 1; i < vector_size(strvec); i++) {
for (p = strvec_slot(strvec, i); *p; ) {
if (need_or) {
if (*p == '|') {
need_or = false;
p++;
continue;
}
report_config_error(CONFIG_GENERAL_ERROR, "Invalid umask syntax %s", FMT_STR_VSLOT(strvec, i));
return;
}
if (!strncmp(p, "IRUSR", 5)) umask_val |= S_IRUSR;
else if (!strncmp(p, "IWUSR", 5)) umask_val |= S_IWUSR;
else if (!strncmp(p, "IXUSR", 5)) umask_val |= S_IXUSR;
else if (!strncmp(p, "IRGRP", 5)) umask_val |= S_IRGRP;
else if (!strncmp(p, "IWGRP", 5)) umask_val |= S_IWGRP;
else if (!strncmp(p, "IXGRP", 5)) umask_val |= S_IXGRP;
else if (!strncmp(p, "IROTH", 5)) umask_val |= S_IROTH;
else if (!strncmp(p, "IWOTH", 5)) umask_val |= S_IWOTH;
else if (!strncmp(p, "IXOTH", 5)) umask_val |= S_IXOTH;
else {
report_config_error(CONFIG_GENERAL_ERROR, "Unknown umask bit %s", p);
return;
}
p += 5;
need_or = true;
}
}
if (!need_or) {
report_config_error(CONFIG_GENERAL_ERROR, "umask missing bit value");
return;
}
}
global_data->umask = umask_val;
umask(umask_val);
}
void
init_global_keywords(bool global_active)
{
@@ -1483,4 +1555,5 @@ init_global_keywords(bool global_active)
install_keyword("vrrp_rx_bufs_policy", &vrrp_rx_bufs_policy_handler);
install_keyword("vrrp_rx_bufs_multiplier", &vrrp_rx_bufs_multiplier_handler);
#endif
install_keyword("umask", &umask_handler);
}
@@ -33,6 +33,7 @@
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
@@ -155,6 +156,10 @@ static struct {
};
#define LOG_FACILITY_MAX ((sizeof(LOG_FACILITY) / sizeof(LOG_FACILITY[0])) - 1)
/* umask settings */
bool umask_cmdline;
static mode_t umask_val = S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH;
/* Control producing core dumps */
static bool set_core_dump_pattern = false;
static bool create_core_dump = false;
@@ -866,6 +871,28 @@ core_dump_init(void)
}
}
static mode_t
set_umask(const char *optarg)
{
long umask_long;
mode_t umask_val;
char *endptr;
umask_long = strtoll(optarg, &endptr, 0);
if (*endptr || umask_long < 0 || umask_long & ~0777L) {
fprintf(stderr, "Invalid --umask option %s", optarg);
return;
}
umask_val = umask_long & 0777;
umask(umask_val);
umask_cmdline = true;
return umask_val;
}
void
initialise_debug_options(void)
{
@@ -1090,6 +1117,7 @@ usage(const char *prog)
fprintf(stderr, " -g, --log-file=FILE Also log to FILE (default /tmp/keepalived.log)\n");
fprintf(stderr, " --flush-log-file Flush log file on write\n");
fprintf(stderr, " -G, --no-syslog Don't log via syslog\n");
fprintf(stderr, " -u, --umask=MASK umask for file creation (in numeric form)\n");
#ifdef _WITH_VRRP_
fprintf(stderr, " -X, --release-vips Drop VIP on transition from signal.\n");
fprintf(stderr, " -V, --dont-release-vrrp Don't remove VRRP VIPs and VROUTEs on daemon stop\n");
@@ -1183,6 +1211,7 @@ parse_cmdline(int argc, char **argv)
int curind;
bool bad_option = false;
unsigned facility;
mode_t new_umask_val;
struct option long_options[] = {
{"use-file", required_argument, NULL, 'f'},
@@ -1200,6 +1229,7 @@ parse_cmdline(int argc, char **argv)
{"log-file", optional_argument, NULL, 'g'},
{"flush-log-file", no_argument, NULL, 2 },
{"no-syslog", no_argument, NULL, 'G'},
{"umask", required_argument, NULL, 'u'},
#ifdef _WITH_VRRP_
{"release-vips", no_argument, NULL, 'X'},
{"dont-release-vrrp", no_argument, NULL, 'V'},
@@ -1252,7 +1282,7 @@ parse_cmdline(int argc, char **argv)
* of longindex, so we need to ensure that before calling getopt_long(), longindex
* is set to a known invalid value */
curind = optind;
while (longindex = -1, (c = getopt_long(argc, argv, ":vhlndDRS:f:p:i:mM::g::Gt::"
while (longindex = -1, (c = getopt_long(argc, argv, ":vhlndu:DRS:f:p:i:mM::g::Gt::"
#if defined _WITH_VRRP_ && defined _WITH_LVS_
"PC"
#endif
@@ -1358,6 +1388,11 @@ parse_cmdline(int argc, char **argv)
__set_bit(NO_SYSLOG_BIT, &debug);
reopen_log = true;
break;
case 'u':
new_umask_val = set_umask(optarg);
if (umask_cmdline)
umask_val = new_umask_val;
break;
case 't':
__set_bit(CONFIG_TEST_BIT, &debug);
__set_bit(DONT_RESPAWN_BIT, &debug);
@@ -1582,6 +1617,9 @@ keepalived_main(int argc, char **argv)
__set_bit(DAEMON_BFD, &daemon_mode);
#endif
/* Set default file creation mask */
umask(022);
/* Open log with default settings so we can log initially */
openlog(PACKAGE_NAME, LOG_PID, log_facility);
@@ -1678,6 +1716,7 @@ keepalived_main(int argc, char **argv)
}
global_data = alloc_global_data();
global_data->umask = umask_val;
read_config_file();
@@ -1809,9 +1848,6 @@ keepalived_main(int argc, char **argv)
exit(0);
}
/* Set file creation mask */
umask(0);
#ifdef _MEM_CHECK_
enable_mem_log_termination();
#endif
@@ -213,6 +213,7 @@ typedef struct _data {
size_t vrrp_rx_bufs_size;
int vrrp_rx_bufs_multiples;
#endif
mode_t umask; /* mask for file creation */
} data_t;
/* Global vars exported */
@@ -96,5 +96,6 @@ extern void initialise_debug_options(void);
extern int keepalived_main(int, char**); /* The "real" main function */
extern unsigned child_wait_time;
extern bool umask_cmdline;
#endif

0 comments on commit c6247a9

Please sign in to comment.