From 4ab20e23751ab0da5abbeee8be338844139c05c6 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Tue, 19 Dec 2017 11:32:56 +0100 Subject: [PATCH] logger: add --no-drop-privileges For use when the daemon is not run as root. Change-Id: I8060f70105bfce6cc5439c1e2aae6493a53cd339 Signed-off-by: Michal Bloch --- src/logger/logger.c | 56 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/logger/logger.c b/src/logger/logger.c index 4a59d26..31401f2 100755 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -193,6 +195,7 @@ struct logger { struct socket_config_data { int permissions; + bool should_chown; char path[MAX_CONF_VAL_LEN]; char owner[MAX_CONF_VAL_LEN]; char group[MAX_CONF_VAL_LEN]; @@ -206,6 +209,7 @@ struct buffer_config_data { struct logger_config_data { struct buf_params buf_params; + bool drop_privileges; list_head logfile_configs; int is_buffer_enabled[LOG_ID_MAX]; struct buffer_config_data buffers[LOG_ID_MAX]; @@ -223,7 +227,7 @@ static void dispatch_event_sock(struct logger *server, struct epoll_event *event static void dispatch_event_reader(struct logger *server, struct epoll_event *event); static void reader_free(struct reader* reader); static void logger_free(struct logger* l); -static int parse_args(int argc, char **argv, struct buf_params *b); +static int parse_args(int argc, char **argv, struct logger_config_data *l); static int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data); static void help(); @@ -1739,10 +1743,12 @@ static int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, if (sock_fd < 0) return sock_fd; - int r = change_owners(data->path, data->owner, data->group); - if (r < 0) { - close(sock_fd); - return r; + if (data->should_chown) { + int r = change_owners(data->path, data->owner, data->group); + if (r < 0) { + close(sock_fd); + return r; + } } init_fd_entity(&sock->fd_entity, dispatch_event_sock, sock); @@ -1946,9 +1952,10 @@ static int do_logger(struct logger* server) * @param[out] data Socket init config data * @param[in] buf_name The name of the buffer the socket belongs to * @param[in] type The name of the buffer type + * @param[in] should_chown Whether the socket should change owner * @return 0 on success, -errno on failure */ -int prepare_socket_data(struct log_config *conf, struct socket_config_data *data, char *buf_name, const char *type) +int prepare_socket_data(struct log_config *conf, struct socket_config_data *data, char *buf_name, const char *type, bool should_chown) { char conf_key[MAX_CONF_KEY_LEN]; int r; @@ -1986,6 +1993,7 @@ int prepare_socket_data(struct log_config *conf, struct socket_config_data *data strncpy(data->path, path, MAX_CONF_VAL_LEN - 1); strncpy(data->owner, owner, MAX_CONF_VAL_LEN - 1); strncpy(data->group, group, MAX_CONF_VAL_LEN - 1); + data->should_chown = should_chown; return 0; } @@ -1996,20 +2004,21 @@ int prepare_socket_data(struct log_config *conf, struct socket_config_data *data * @param[in] conf Config database * @param[out] data Buffer init config data * @param[in] buf_id Index of the buffer to work with + * @param[in] should_sockets_chown Whether sockets belonging to the buffer should change owner * @return 0 on success, -errno on failure */ -int prepare_buffer_data(struct log_config *conf, struct buffer_config_data *data, log_id_t buf_id) +int prepare_buffer_data(struct log_config *conf, struct buffer_config_data *data, log_id_t buf_id, bool should_sockets_chown) { char * const buf_name = log_name_by_id(buf_id); char * validity_check_ptr; char conf_key[MAX_CONF_KEY_LEN]; int r; - r = prepare_socket_data(conf, &data->write_socket, buf_name, "write"); + r = prepare_socket_data(conf, &data->write_socket, buf_name, "write", should_sockets_chown); if (r < 0) return r; - r = prepare_socket_data(conf, &data->ctl_socket, buf_name, "ctl"); + r = prepare_socket_data(conf, &data->ctl_socket, buf_name, "ctl", should_sockets_chown); if (r < 0) return r; @@ -2066,7 +2075,7 @@ int prepare_config_data(struct logger_config_data *data, int argc, char **argv) memset(data, 0, sizeof *data); - int ret = parse_args(argc, argv, &data->buf_params); + int ret = parse_args(argc, argv, data); if (ret != 0) { help(); return ret; @@ -2108,7 +2117,7 @@ int prepare_config_data(struct logger_config_data *data, int argc, char **argv) for (log_id_t buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id) { if (data->is_buffer_enabled[buf_id]) { - ret = prepare_buffer_data(&conf, data->buffers + buf_id, buf_id); + ret = prepare_buffer_data(&conf, data->buffers + buf_id, buf_id, data->drop_privileges); if (ret < 0) goto end; } @@ -2150,18 +2159,29 @@ static void help() * @details Parses execution parameters of the program * @param[in] argc Argument count * @param[in] argv Argument values - * @param[out] b Buffering parameters + * @param[out] l Configuration for the logger server * @return 0 or 1 on success, else -errno. Nonzero if the program is to close. */ -static int parse_args(int argc, char **argv, struct buf_params *b) +static int parse_args(int argc, char **argv, struct logger_config_data *l) { + assert(l); + int option; + struct buf_params *const b = &l->buf_params; + l->drop_privileges = true; b->time = BUF_PARAM_TIME_DEFAULT; b->bytes = BUF_PARAM_BYTES_DEFAULT; - while ((option = getopt(argc, argv, "hb:t:")) != -1) { + static const struct option long_options[] = { + {"no-drop-privileges", no_argument, NULL, 0}, + {0} + }; + while ((option = getopt_long(argc, argv, "hb:t:", long_options, NULL)) != -1) { switch (option) { + case 0: + l->drop_privileges = false; + break; case 't': if (!isdigit(optarg[0])) return -EINVAL; @@ -2221,9 +2241,11 @@ static int finalize_init(struct logger_config_data *data, struct logger *server) { sd_notify(0, "READY=1"); - int r = reset_self_privileges(); - if (r < 0) - return r; + if (data->drop_privileges) { + int r = reset_self_privileges(); + if (r < 0) + return r; + } //create files after resetting self privileges list_foreach(data->logfile_configs, server, parse_logfile_config); -- 2.7.4