From 99f31a89d2f5803fe2d6229f2557e72efb3ef95f Mon Sep 17 00:00:00 2001
From: Quentin Armitage <quentin@armitage.org.uk>
Date: Tue, 28 Mar 2017 09:11:44 +0100
Subject: [PATCH] Make dynamic flag bool
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
Fix releasing malloc'd memory for saved core pattern
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
Fix detecting default script uid/gid
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
Don't complain about keepalived_script user if not needed
keepalived logged a warning every time if the keepalived_script user
didn't exist. We only need that warning if there is a script that uses
the default user, and an alternative defult user isn't specified.
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
---
doc/keepalived.conf.SYNOPSIS | 30 +++++----
doc/man/man5/keepalived.conf.5 | 4 +-
keepalived/check/check_misc.c | 72 ++++++++++++++++-----
keepalived/check/check_parser.c | 9 +--
keepalived/core/global_parser.c | 49 +-------------
keepalived/core/main.c | 15 +----
keepalived/include/check_misc.h | 2 +-
keepalived/include/main.h | 2 -
keepalived/vrrp/vrrp_data.c | 3 +-
keepalived/vrrp/vrrp_parser.c | 46 ++++++++++---
keepalived/vrrp/vrrp_print.c | 1 +
lib/notify.c | 140 ++++++++++++++++++++++++++++++++++------
lib/notify.h | 7 +-
13 files changed, 242 insertions(+), 138 deletions(-)
diff --git a/doc/keepalived.conf.SYNOPSIS b/doc/keepalived.conf.SYNOPSIS
index 5b1dfb8..90eb83d 100644
--- a/doc/keepalived.conf.SYNOPSIS
+++ b/doc/keepalived.conf.SYNOPSIS
@@ -568,12 +568,14 @@ virtual_server group <STRING> { # VS group declaration
weight <INTEGER> # weight to use (default: 1)
inhibit_on_failure # Set weight to 0 on healthchecker
# failure
- notify_up <STRING>|<QUOTED-STRING> # Script to launch when
- # healthchecker consider service
- # as up.
- notify_down <STRING>|<QUOTED-STRING> # Script to launch when
- # healthchecker consider service
- # as down.
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]]
+ # Script to launch when
+ # healthchecker consider service
+ # as up.
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]]
+ # Script to launch when
+ # healthchecker consider service
+ # as down.
HTTP_GET|SSL_GET { # HTTP and SSL healthcheckers
url { # A set of url to test
@@ -603,8 +605,8 @@ virtual_server group <STRING> { # VS group declaration
real_server <IP ADDRESS> <PORT> { # Idem
weight <INTEGER> # Idem
inhibit_on_failure # Idem
- notify_up <STRING>|<QUOTED-STRING> # Idem
- notify_down <STRING>|<QUOTED-STRING> # Idem
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
TCP_CHECK { # TCP healthchecker
connect_ip <IP ADDRESS> # IP address to connect
@@ -620,8 +622,8 @@ virtual_server group <STRING> { # VS group declaration
real_server <IP ADDRESS> <PORT> { # Idem
weight <INTEGER> # Idem
inhibit_on_failure # Idem
- notify_up <STRING>|<QUOTED-STRING> # Idem
- notify_down <STRING>|<QUOTED-STRING> # Idem
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
SMTP_CHECK { # SMTP healthchecker
connect_ip <IP ADDRESS> # Optional IP address to connect to
@@ -658,8 +660,8 @@ virtual_server group <STRING> { # VS group declaration
real_server <IP ADDRESS> <PORT> { # Idem
weight <INTEGER> # Idem
inhibit_on_failure # Idem
- notify_up <STRING>|<QUOTED-STRING> # Idem
- notify_down <STRING>|<QUOTED-STRING> # Idem
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
DNS_CHECK { # DNS healthchecker
connect_ip <IP ADDRESS> # Optional IP address to connect to
@@ -677,8 +679,8 @@ virtual_server group <STRING> { # VS group declaration
real_server <IP ADDRESS> <PORT> { # Idem
weight <INTEGER> # Idem
inhibit_on_failure # Idem
- notify_up <STRING>|<QUOTED-STRING> # Idem
- notify_down <STRING>|<QUOTED-STRING> # Idem
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]] # Idem
MISC_CHECK { # MISC healthchecker
misc_path <STRING>|<QUOTED-STRING> # External system script or program
diff --git a/doc/man/man5/keepalived.conf.5 b/doc/man/man5/keepalived.conf.5
index 9ce2206..be33063 100644
--- a/doc/man/man5/keepalived.conf.5
+++ b/doc/man/man5/keepalived.conf.5
@@ -711,10 +711,10 @@ A virtual_server can be a declaration of one of
# Script to execute when healthchecker
# considers service as up.
- notify_up <STRING>|<QUOTED-STRING>
+ notify_up <STRING>|<QUOTED-STRING> [username [groupname]]
# Script to execute when healthchecker
# considers service as down.
- notify_down <STRING>|<QUOTED-STRING>
+ notify_down <STRING>|<QUOTED-STRING> [username [groupname]]
uthreshold <INTEGER> # maximum number of connections to server
lthreshold <INTEGER> # minimum number of connections to server
diff --git a/keepalived/check/check_misc.c b/keepalived/check/check_misc.c
index ccb9b63..a041d81 100644
--- a/keepalived/check/check_misc.c
+++ b/keepalived/check/check_misc.c
@@ -44,6 +44,11 @@ static int misc_check_thread(thread_t *);
static int misc_check_child_thread(thread_t *);
static int misc_check_child_timeout_thread(thread_t *);
+static bool script_user_set;
+static bool remove_script;
+static misc_checker_t *misck_checker;
+
+
/* Configuration stream handling */
static void
free_misc_check(void *data)
@@ -70,49 +75,83 @@ dump_misc_check(void *data)
static void
misc_check_handler(__attribute__((unused)) vector_t *strvec)
{
- misc_checker_t *misck_checker = (misc_checker_t *) MALLOC(sizeof (misc_checker_t));
-
- misck_checker->uid = default_script_uid;
- misck_checker->gid = default_script_gid;
+ misck_checker = (misc_checker_t *) MALLOC(sizeof (misc_checker_t));
- /* queue new checker */
- queue_checker(free_misc_check, dump_misc_check, misc_check_thread,
- misck_checker, NULL);
+ script_user_set = false;
}
static void
misc_path_handler(vector_t *strvec)
{
- misc_checker_t *misck_checker = CHECKER_GET();
+ if (!misck_checker)
+ return;
+
misck_checker->path = CHECKER_VALUE_STRING(strvec);
}
static void
misc_timeout_handler(vector_t *strvec)
{
- misc_checker_t *misck_checker = CHECKER_GET();
+ if (!misck_checker)
+ return;
+
misck_checker->timeout = CHECKER_VALUE_UINT(strvec) * TIMER_HZ;
}
static void
misc_dynamic_handler(__attribute__((unused)) vector_t *strvec)
{
- misc_checker_t *misck_checker = CHECKER_GET();
- misck_checker->dynamic = 1;
+ if (!misck_checker)
+ return;
+
+ misck_checker->dynamic = true;
}
static void
misc_user_handler(vector_t *strvec)
{
- misc_checker_t *misck_checker = CHECKER_GET();
+ if (!misck_checker)
+ return;
if (vector_size(strvec) < 2) {
log_message(LOG_INFO, "No user specified for misc checker script %s", misck_checker->path);
return;
}
- if (set_script_uid_gid(strvec, 1, &misck_checker->uid, &misck_checker->gid))
- log_message(LOG_INFO, "Failed to set uid/gid for misc checker script %s", misck_checker->path);
+ if (set_script_uid_gid(strvec, 1, &misck_checker->uid, &misck_checker->gid)) {
+ log_message(LOG_INFO, "Failed to set uid/gid for misc checker script %s - removing", misck_checker->path);
+ FREE(misck_checker);
+ misck_checker = NULL;
+ }
+ else
+ script_user_set = true;
+}
+
+static void
+misc_end_handler(void)
+{
+ if (!misck_checker)
+ return;
+
+ if (!script_user_set)
+ {
+log_message(LOG_INFO, "remove_script 1 %d", remove_script);
+ if ( set_default_script_user(NULL, NULL, global_data->script_security)) {
+ log_message(LOG_INFO, "Unable to set default user for misc script %s - removing", misck_checker->path);
+ FREE(misck_checker);
+ misck_checker = NULL;
+ return;
+ }
+
+log_message(LOG_INFO, "Setting uid.gid");
+ misck_checker->uid = default_script_uid;
+ misck_checker->gid = default_script_gid;
+ }
+
+ /* queue new checker */
+ queue_checker(free_misc_check, dump_misc_check, misc_check_thread, misck_checker, NULL);
+ misck_checker = NULL;
+log_message(LOG_INFO, "Leaving misc_end_handler");
}
void
@@ -125,6 +164,7 @@ install_misc_check_keyword(void)
install_keyword("misc_dynamic", &misc_dynamic_handler);
install_keyword("warmup", &warmup_handler);
install_keyword("user", &misc_user_handler);
+ install_sublevel_end_handler(&misc_end_handler);
install_sublevel_end();
}
@@ -251,13 +291,13 @@ misc_check_child_thread(thread_t * thread)
int status;
status = WEXITSTATUS(wait_status);
if (status == 0 ||
- (misck_checker->dynamic == 1 && status >= 2 && status <= 255)) {
+ (misck_checker->dynamic && status >= 2 && status <= 255)) {
/*
* The actual weight set when using misc_dynamic is two less than
* the exit status returned. Effective range is 0..253.
* Catch legacy case of status being 0 but misc_dynamic being set.
*/
- if (misck_checker->dynamic == 1 && status != 0)
+ if (misck_checker->dynamic && status != 0)
update_svr_wgt(status - 2, checker->vs,
checker->rs, true);
diff --git a/keepalived/check/check_parser.c b/keepalived/check/check_parser.c
index 2adac98..382861c 100644
--- a/keepalived/check/check_parser.c
+++ b/keepalived/check/check_parser.c
@@ -322,14 +322,7 @@ inhibit_handler(__attribute__((unused)) vector_t *strvec)
static inline notify_script_t*
set_check_notify_script(vector_t *strvec)
{
- notify_script_t *script = notify_script_init(strvec, default_script_uid, default_script_gid);
-
- if (vector_size(strvec) > 2 ) {
- if (set_script_uid_gid(strvec, 2, &script->uid, &script->gid))
- log_message(LOG_INFO, "Invalid user/group for quorum/notify script %s", script->name);
- }
-
- return script;
+ return notify_script_init(strvec, "quorum/notify", global_data->script_security);
}
static void
notify_up_handler(vector_t *strvec)
diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c
index 45d4cfb..a59fbc0 100644
--- a/keepalived/core/global_parser.c
+++ b/keepalived/core/global_parser.c
@@ -701,53 +701,6 @@ use_pid_dir_handler(__attribute__((unused)) vector_t *strvec)
use_pid_dir = true;
}
-bool
-set_script_uid_gid(vector_t *strvec, unsigned keyword_offset, uid_t *uid_p, gid_t *gid_p)
-{
- char *username;
- char *groupname;
- uid_t uid;
- gid_t gid;
- struct passwd pwd;
- struct passwd *pwd_p;
- struct group grp;
- struct group *grp_p;
- int ret;
- char buf[getpwnam_buf_len];
-
- username = strvec_slot(strvec, keyword_offset);
-
- if ((ret = getpwnam_r(username, &pwd, buf, sizeof(buf), &pwd_p))) {
- log_message(LOG_INFO, "Unable to resolve script username '%s' - ignoring", username);
- return true;
- }
- if (!pwd_p) {
- log_message(LOG_INFO, "Script user '%s' does not exist", username);
- return true;
- }
-
- uid = pwd.pw_uid;
- gid = pwd.pw_gid;
-
- if (vector_size(strvec) > keyword_offset + 1) {
- groupname = strvec_slot(strvec, keyword_offset + 1);
- if ((ret = getgrnam_r(groupname, &grp, buf, sizeof(buf), &grp_p))) {
- log_message(LOG_INFO, "Unable to resolve script group name '%s' - ignoring", groupname);
- return true;
- }
- if (!grp_p) {
- log_message(LOG_INFO, "Script group '%s' does not exist", groupname);
- return true;
- }
- gid = grp.gr_gid;
- }
-
- *uid_p = uid;
- *gid_p = gid;
-
- return false;
-}
-
static void
script_user_handler(vector_t *strvec)
{
@@ -756,7 +709,7 @@ script_user_handler(vector_t *strvec)
return;
}
- if (set_script_uid_gid(strvec, 1, &default_script_uid, &default_script_gid))
+ if (set_default_script_user(strvec_slot(strvec, 1), vector_size(strvec) > 2 ? strvec_slot(strvec, 2) : NULL, true))
log_message(LOG_INFO, "Error setting global script uid/gid");
}
diff --git a/keepalived/core/main.c b/keepalived/core/main.c
index 55eb263..95bb76a 100644
--- a/keepalived/core/main.c
+++ b/keepalived/core/main.c
@@ -119,6 +119,9 @@ free_parent_mallocs_startup(bool am_child)
#else
free(syslog_ident);
#endif
+
+ if (orig_core_dump_pattern)
+ FREE_PTR(orig_core_dump_pattern);
}
if (free_main_pidfile) {
@@ -765,7 +768,6 @@ keepalived_main(int argc, char **argv)
bool report_stopped = true;
struct utsname uname_buf;
char *end;
- long buf_len;
/* Init debugging level */
debug = 0;
@@ -814,17 +816,6 @@ keepalived_main(int argc, char **argv)
netlink_set_recv_buf_size();
- set_default_script_user(&default_script_uid, &default_script_gid);
-
- /* Get buffer length needed for getpwnam_r/getgrnam_r */
- if ((buf_len = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1)
- getpwnam_buf_len = 1024; /* A safe default if no value is returned */
- else
- getpwnam_buf_len = (size_t)buf_len;
- if ((buf_len = sysconf(_SC_GETGR_R_SIZE_MAX)) != -1 &&
- (size_t)buf_len > getpwnam_buf_len)
- getpwnam_buf_len = (size_t)buf_len;
-
/* Some functionality depends on kernel version, so get the version here */
if (uname(&uname_buf))
log_message(LOG_INFO, "Unable to get uname() information - error %d", errno);
diff --git a/keepalived/include/check_misc.h b/keepalived/include/check_misc.h
index ed0d962..ec97149 100644
--- a/keepalived/include/check_misc.h
+++ b/keepalived/include/check_misc.h
@@ -36,7 +36,7 @@
typedef struct _misc_checker {
char *path;
unsigned long timeout;
- int dynamic; /* 0: old-style, 1: exit code from checker affects weight */
+ bool dynamic; /* false: old-style, true: exit code from checker affects weight */
bool forcing_termination; /* Set if we have sent the process a SIGTERM */
uid_t uid; /* uid for script execution */
gid_t gid; /* gid for script execution */
diff --git a/keepalived/include/main.h b/keepalived/include/main.h
index d125566..eebde77 100644
--- a/keepalived/include/main.h
+++ b/keepalived/include/main.h
@@ -73,8 +73,6 @@ extern bool namespace_with_ipsets; /* override for namespaces with ipsets on Lin
#endif
extern char *instance_name; /* keepalived instance name */
extern bool use_pid_dir; /* pid files in /var/run/keepalived */
-extern uid_t default_script_uid; /* Default user/group for script execution */
-extern gid_t default_script_gid;
extern unsigned os_major; /* Kernel version */
extern unsigned os_minor;
extern unsigned os_release;
diff --git a/keepalived/vrrp/vrrp_data.c b/keepalived/vrrp/vrrp_data.c
index 76f17a4..b5c59df 100644
--- a/keepalived/vrrp/vrrp_data.c
+++ b/keepalived/vrrp/vrrp_data.c
@@ -160,8 +160,7 @@ dump_vscript(void *data)
str = (vscript->result >= vscript->rise) ? "GOOD" : "BAD";
}
log_message(LOG_INFO, " Status = %s", str);
- if (vscript->uid || vscript->gid)
- log_message(LOG_INFO, " Script uid:gid = %d:%d", vscript->uid, vscript->gid);
+ log_message(LOG_INFO, " Script uid:gid = %d:%d", vscript->uid, vscript->gid);
}
diff --git a/keepalived/vrrp/vrrp_parser.c b/keepalived/vrrp/vrrp_parser.c
index 7a38315..c774dec 100644
--- a/keepalived/vrrp/vrrp_parser.c
+++ b/keepalived/vrrp/vrrp_parser.c
@@ -48,6 +48,9 @@
#include "bitops.h"
#include "notify.h"
+static bool script_user_set;
+static bool remove_script;
+
/* Static addresses handler */
static void
static_addresses_handler(__attribute__((unused)) vector_t *strvec)
@@ -120,14 +123,7 @@ vrrp_group_handler(vector_t *strvec)
static inline notify_script_t*
set_vrrp_notify_script(vector_t *strvec)
{
- notify_script_t *script = notify_script_init(strvec, default_script_uid, default_script_gid);
-
- if (vector_size(strvec) > 2) {
- if (set_script_uid_gid(strvec, 2, &script->uid, &script->gid))
- log_message(LOG_INFO, "Invalid user/group for notify script %s", script->name);
- }
-
- return script;
+ return notify_script_init(strvec, "notify", global_data->script_security);
}
static void
@@ -680,6 +676,8 @@ static void
vrrp_script_handler(vector_t *strvec)
{
alloc_vrrp_script(strvec_slot(strvec, 1));
+ script_user_set = false;
+ remove_script = false;
}
static void
vrrp_vscript_script_handler(vector_t *strvec)
@@ -731,8 +729,35 @@ static void
vrrp_vscript_user_handler(vector_t *strvec)
{
vrrp_script_t *vscript = LIST_TAIL_DATA(vrrp_data->vrrp_script);
- if (set_script_uid_gid(strvec, 1, &vscript->uid, &vscript->gid))
- log_message(LOG_INFO, "Unable to set uid/gid for script %s", vscript->script);
+ if (set_script_uid_gid(strvec, 1, &vscript->uid, &vscript->gid)) {
+ log_message(LOG_INFO, "Unable to set uid/gid for script %s - disabling", vscript->script);
+ remove_script = true;
+ }
+ else
+ script_user_set = true;
+}
+static void
+vrrp_vscript_end_handler(void)
+{
+ vrrp_script_t *vscript = LIST_TAIL_DATA(vrrp_data->vrrp_script);
+
+ if (script_user_set)
+ return;
+
+ if (!remove_script &&
+ set_default_script_user(NULL, NULL, global_data->script_security)) {
+ log_message(LOG_INFO, "Unable to set default user for track script %s - removing", vscript->script);
+ remove_script = true;
+ }
+
+ if (remove_script) {
+ free_list_element(vrrp_data->vrrp_script, vrrp_data->vrrp_script->tail);
+ return;
+ }
+
+ vscript->uid = default_script_uid;
+ vscript->gid = default_script_gid;
+
}
static void
vrrp_vscript_init_fail_handler(__attribute__((unused)) vector_t *strvec)
@@ -964,6 +989,7 @@ init_vrrp_keywords(bool active)
install_keyword("fall", &vrrp_vscript_fall_handler);
install_keyword("user", &vrrp_vscript_user_handler);
install_keyword("init_fail", &vrrp_vscript_init_fail_handler);
+ install_sublevel_end_handler(&vrrp_vscript_end_handler);
}
vector_t *
diff --git a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c
index 7adb701..54da044 100644
--- a/keepalived/vrrp/vrrp_print.c
+++ b/keepalived/vrrp/vrrp_print.c
@@ -92,6 +92,7 @@ vscript_print(FILE *file, void *data)
fprintf(file, " Rise = %d\n", vscript->rise);
fprintf(file, " Full = %d\n", vscript->fall);
fprintf(file, " Insecure = %s\n", vscript->insecure ? "yes" : "no");
+ fprintf(file, " uid:gid = %d:%d\n", vscript->uid, vscript->gid);
switch (vscript->result) {
case VRRP_SCRIPT_STATUS_INIT:
diff --git a/lib/notify.c b/lib/notify.c
index d92c50d..a8742fe 100644
--- a/lib/notify.c
+++ b/lib/notify.c
@@ -44,10 +44,15 @@
#include "vector.h"
#include "parser.h"
-size_t getpwnam_buf_len; /* Buffer length needed for getpwnam_r/getgrname_r */
+uid_t default_script_uid; /* Default user/group for script execution */
+gid_t default_script_gid;
+static bool default_script_uid_set = false;
+static bool default_user_fail = false; /* Set if failed to set default user,
+ unless it defaults to root */
static char *path;
static bool path_is_malloced;
+static size_t getpwnam_buf_len; /* Buffer length needed for getpwnam_r/getgrname_r */
/* perform a system call */
static int
@@ -565,40 +570,135 @@ check_notify_script_secure(notify_script_t **script_p, bool script_security, boo
return flags;
}
-/* The default script user/group is keepalived_script if it exists, or root otherwise */
-void
-set_default_script_user(uid_t *uid, gid_t *gid)
+static void
+set_pwnam_buf_len(void)
+{
+ long buf_len;
+
+ /* Get buffer length needed for getpwnam_r/getgrnam_r */
+ if ((buf_len = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1)
+ getpwnam_buf_len = 1024; /* A safe default if no value is returned */
+ else
+ getpwnam_buf_len = (size_t)buf_len;
+ if ((buf_len = sysconf(_SC_GETGR_R_SIZE_MAX)) != -1 &&
+ (size_t)buf_len > getpwnam_buf_len)
+ getpwnam_buf_len = (size_t)buf_len;
+}
+
+bool
+set_uid_gid(const char *username, const char *groupname, uid_t *uid_p, gid_t *gid_p, bool default_user)
{
- char buf[getpwnam_buf_len];
- char *default_user_name = "keepalived_script";
+ uid_t uid;
+ gid_t gid;
struct passwd pwd;
struct passwd *pwd_p;
+ struct group grp;
+ struct group *grp_p;
+ int ret;
+ bool using_default_default_user = false;
+
+ if (!getpwnam_buf_len)
+ set_pwnam_buf_len();
- if (getpwnam_r(default_user_name, &pwd, buf, sizeof(buf), &pwd_p)) {
- log_message(LOG_INFO, "Unable to resolve default script username '%s' - ignoring", default_user_name);
- return;
+ {
+ char buf[getpwnam_buf_len];
+
+ if (default_user && !username) {
+ using_default_default_user = true;
+ username = "keepalived_script";
+ }
+
+ if ((ret = getpwnam_r(username, &pwd, buf, sizeof(buf), &pwd_p))) {
+ log_message(LOG_INFO, "Unable to resolve %sscript username '%s' - ignoring", default_user ? "default " : "", username);
+ return true;
+ }
+ if (!pwd_p) {
+ if (using_default_default_user)
+ log_message(LOG_INFO, "WARNING - default user '%s' for script execution does not exist - please create.", username);
+ else
+ log_message(LOG_INFO, "%script user '%s' does not exist", default_user ? "Default s" : "S", username);
+ return true;
+ }
+
+ uid = pwd.pw_uid;
+ gid = pwd.pw_gid;
+
+ if (groupname) {
+ if ((ret = getgrnam_r(groupname, &grp, buf, sizeof(buf), &grp_p))) {
+ log_message(LOG_INFO, "Unable to resolve %sscript group name '%s' - ignoring", default_user ? "default " : "", groupname);
+ return true;
+ }
+ if (!grp_p) {
+ log_message(LOG_INFO, "%script group '%s' does not exist", default_user ? "Default s" : "S", groupname);
+ return true;
+ }
+ gid = grp.gr_gid;
+ }
+
+ *uid_p = uid;
+ *gid_p = gid;
}
- if (!pwd_p) {
- /* The username does not exist */
- log_message(LOG_INFO, "WARNING - default user '%s' for script execution does not exist - please create.", default_user_name);
- return;
+
+ return false;
+}
+
+bool
+set_default_script_user(const char *username, const char *groupname, bool script_security)
+{
+ if (!default_script_uid_set || username) {
+ /* Even if we fail to set it, there is no point in trying again */
+ default_script_uid_set = true;
+
+ if (set_uid_gid(username, groupname, &default_script_uid, &default_script_gid, true)) {
+ if (username || script_security)
+ default_user_fail = true;
+ }
+ else
+ default_user_fail = false;
}
- *uid = pwd.pw_uid;
- *gid = pwd.pw_gid;
+ return default_user_fail;
+}
+
+bool
+set_script_uid_gid(vector_t *strvec, unsigned keyword_offset, uid_t *uid_p, gid_t *gid_p)
+{
+ char *username;
+ char *groupname;
+
+ username = strvec_slot(strvec, keyword_offset);
+ if (vector_size(strvec) > keyword_offset + 1)
+ groupname = strvec_slot(strvec, keyword_offset + 1);
+ else
+ groupname = NULL;
- log_message(LOG_INFO, "Setting default script user to '%s', uid:gid %d:%d", default_user_name, pwd.pw_uid, pwd.pw_gid);
+ return set_uid_gid(username, groupname, uid_p, gid_p, false);
}
notify_script_t*
-notify_script_init(vector_t *strvec, uid_t uid, gid_t gid)
+notify_script_init(vector_t *strvec, const char *type, bool script_security)
{
notify_script_t *script = MALLOC(sizeof(notify_script_t));
script->name = set_value(strvec);
- script->uid = uid;
- script->gid = gid;
+
+ if (vector_size(strvec) > 2) {
+ if (set_script_uid_gid(strvec, 2, &script->uid, &script->gid)) {
+ log_message(LOG_INFO, "Invalid user/group for %s script %s - ignoring", type, script->name);
+ FREE(script);
+ return NULL;
+ }
+ }
+ else {
+ if (set_default_script_user(NULL, NULL, script_security)) {
+ log_message(LOG_INFO, "Failed to set default user for %s script %s - ignoring", type, script->name);
+ FREE(script);
+ return NULL;
+ }
+
+ script->uid = default_script_uid;
+ script->gid = default_script_gid;
+ }
return script;
}
-
diff --git a/lib/notify.h b/lib/notify.h
index ac07edb..3d092ea 100644
--- a/lib/notify.h
+++ b/lib/notify.h
@@ -56,7 +56,8 @@ free_notify_script(notify_script_t **script)
}
/* Global variables */
-extern size_t getpwnam_buf_len; /* Buffer length needed for getpwnam_r/getgrnam_r */
+extern uid_t default_script_uid; /* Default user/group for script execution */
+extern gid_t default_script_gid;
/* prototypes */
extern int system_call_script(thread_master_t *, int (*) (thread_t *), void *, unsigned long, const char*, uid_t, gid_t);
@@ -64,7 +65,7 @@ extern int notify_exec(const notify_script_t *);
extern void script_killall(thread_master_t *, int);
extern int check_script_secure(notify_script_t *, bool, bool);
extern int check_notify_script_secure(notify_script_t **, bool, bool);
-extern void set_default_script_user(uid_t *, gid_t *);
-extern notify_script_t* notify_script_init(vector_t *, uid_t, gid_t);
+extern bool set_default_script_user(const char *, const char *, bool);
+extern notify_script_t* notify_script_init(vector_t *, const char *, bool);
#endif
--
2.9.4