2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 09:57:41 +00:00
sudo/logsrvd/logsrvd_conf.c

236 lines
5.7 KiB
C
Raw Normal View History

2019-10-24 20:04:31 -06:00
/*
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# include "compat/stdbool.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log_server.pb-c.h"
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
#include "sudo_compat.h"
#include "sudo_debug.h"
#include "sudo_util.h"
#include "sudo_fatal.h"
#include "sudo_iolog.h"
2019-10-24 20:04:31 -06:00
#include "pathnames.h"
#include "logsrvd.h"
enum config_type {
CONF_BOOL,
CONF_INT,
CONF_UINT,
CONF_MODE,
CONF_STR
};
union config_value {
char *strval;
int intval;
unsigned int uintval;
mode_t modeval;
bool boolval;
};
struct logsrvd_config_table {
char *conf_str;
enum config_type conf_type;
union config_value conf_val;
};
/* Indexes into conf_table */
#define LOGSRVD_CONF_IOLOG_DIR 0
#define LOGSRVD_CONF_IOLOG_FILE 1
#define LOGSRVD_CONF_IOLOG_FLUSH 2
#define LOGSRVD_CONF_IOLOG_COMPRESS 3
#define LOGSRVD_CONF_IOLOG_USER 4
#define LOGSRVD_CONF_IOLOG_GROUP 5
#define LOGSRVD_CONF_IOLOG_MODE 6
#define LOGSRVD_CONF_MAXSEQ 7
/* XXX - use callbacks into iolog.c instead */
static struct logsrvd_config_table conf_table[] = {
{ "iolog_dir", CONF_STR, { .strval = _PATH_SUDO_IO_LOGDIR } },
{ "iolog_file", CONF_STR, { .strval = "%{seq}" } },
{ "iolog_flush", CONF_BOOL, { .boolval = true } },
{ "iolog_compress", CONF_BOOL, { .boolval = false } },
{ "iolog_user", CONF_STR, { .strval = NULL } },
{ "iolog_group", CONF_STR, { .strval = NULL } },
{ "iolog_mode", CONF_MODE, { .intval = S_IRUSR|S_IWUSR } },
{ "maxseq", CONF_UINT, { .intval = SESSID_MAX } },
{ NULL }
};
static bool
parse_value(struct logsrvd_config_table *ct, const char *val)
{
int ival;
unsigned int uval;
mode_t mode;
const char *errstr;
debug_decl(parse_value, SUDO_DEBUG_UTIL)
switch (ct->conf_type) {
case CONF_BOOL:
ival = sudo_strtobool(val);
if (ival == -1)
debug_return_bool(false);
ct->conf_val.boolval = ival;
break;
case CONF_INT:
ival = sudo_strtonum(val, INT_MIN, INT_MAX, &errstr);
if (errstr != NULL)
debug_return_bool(false);
ct->conf_val.intval = ival;
break;
case CONF_UINT:
uval = sudo_strtonum(val, 0, UINT_MAX, &errstr);
if (errstr != NULL)
debug_return_bool(false);
ct->conf_val.uintval = uval;
break;
case CONF_MODE:
mode = sudo_strtomode(val, &errstr);
if (errstr != NULL)
debug_return_bool(false);
ct->conf_val.modeval = mode;
break;
case CONF_STR:
ct->conf_val.strval = strdup(val);
if (ct->conf_val.strval == NULL)
debug_return_bool(false);
break;
default:
debug_return_bool(false);
}
debug_return_bool(true);
}
void
logsrvd_conf_read(const char *path)
{
unsigned int lineno = 0;
size_t linesize = 0;
char *line = NULL;
FILE *fp;
debug_decl(read_config, SUDO_DEBUG_UTIL)
if ((fp = fopen(path, "r")) == NULL) {
if (errno != ENOENT)
sudo_warn("%s", path);
debug_return;
}
while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) {
struct logsrvd_config_table *ct;
char *ep, *val;
// XXX - warn about bogus lines
if ((ep = strchr(line, '=')) == NULL)
continue;
val = ep + 1;
while (isspace((unsigned char)*val))
val++;
while (ep > line && isspace((unsigned char)ep[-1]))
ep--;
*ep = '\0';
for (ct = conf_table; ct->conf_str != NULL; ct++) {
if (strcmp(line, ct->conf_str) == 0) {
if (!parse_value(ct, val))
sudo_warnx("invalid value for %s: %s", ct->conf_str, val);
break;
}
}
}
#if 0
/*
* TODO: iolog_dir, iolog_file, iolog_flush, iolog_compress
*/
iolog_set_user(conf_table[LOGSRVD_CONF_IOLOG_USER].conf_val.strval);
iolog_set_group(conf_table[LOGSRVD_CONF_IOLOG_GROUP].conf_val.strval);
iolog_set_mode(conf_table[LOGSRVD_CONF_IOLOG_MODE].conf_val.modeval);
/* XXX - expects a string */
iolog_set_max_sessid(conf_table[LOGSRVD_CONF_MAXSEQ].conf_val.uintval);
#endif
debug_return;
}
/* XXX - use callbacks instead */
const char *
logsrvd_conf_iolog_dir(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_DIR].conf_val.strval;
}
const char *
logsrvd_conf_iolog_file(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_FILE].conf_val.strval;
}
const char *
logsrvd_conf_iolog_user(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_USER].conf_val.strval;
}
const char *
logsrvd_conf_iolog_group(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_GROUP].conf_val.strval;
}
bool
logsrvd_conf_iolog_flush(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_FLUSH].conf_val.boolval;
}
bool
logsrvd_conf_iolog_compress(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_COMPRESS].conf_val.boolval;
}
mode_t
logsrvd_conf_iolog_mode(void)
{
return conf_table[LOGSRVD_CONF_IOLOG_MODE].conf_val.modeval;
}
unsigned int
logsrvd_conf_maxseq(void)
{
return conf_table[LOGSRVD_CONF_MAXSEQ].conf_val.uintval;
}