diff options
author | Robbie Harwood (frozencemetery) <rharwood@redhat.com> | 2015-08-25 14:10:37 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2015-09-04 14:25:09 -0400 |
commit | f2385558dd9542ca0a88f3386aa5833a23e5eb8b (patch) | |
tree | fbacdf78d30d92cbf752439cc2d9d200f225bfab | |
parent | 9f1a8a8777ae144ccf34c6406e9bc8fa930e0047 (diff) | |
download | gss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.tar.gz gss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.tar.xz gss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.zip |
Add support for config directories
Option '-C|--configdir' has been added, and defaults to /etc/gssproxy. File
"gssproxy.conf" and all files of the form "##-foo.conf" will be read from that
directory.
Ticket: https://fedorahosted.org/gss-proxy/ticket/122
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Simo Sorce <simo@redhat.com>
-rw-r--r-- | proxy/src/gp_config.c | 154 | ||||
-rw-r--r-- | proxy/src/gp_config.h | 2 | ||||
-rw-r--r-- | proxy/src/gp_proxy.h | 5 | ||||
-rw-r--r-- | proxy/src/gssproxy.c | 11 |
4 files changed, 142 insertions, 30 deletions
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index 2812e88..61e32b8 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -427,6 +427,7 @@ done: } static int gp_init_ini_context(const char *config_file, + const char *config_dir, struct gp_ini_context **ctxp) { struct gp_ini_context *ctx; @@ -441,7 +442,7 @@ static int gp_init_ini_context(const char *config_file, return ENOENT; } - ret = gp_config_init(config_file, ctx); + ret = gp_config_init(config_file, config_dir, ctx); if (ret) { free(ctx); @@ -457,7 +458,7 @@ int load_config(struct gp_config *cfg) const char *tmpstr; int ret; - ret = gp_init_ini_context(cfg->config_file, &ctx); + ret = gp_init_ini_context(cfg->config_file, cfg->config_dir, &ctx); if (ret) { return ret; } @@ -499,10 +500,11 @@ done: return ret; } -struct gp_config *read_config(char *config_file, char *socket_name, - int opt_daemonize) +struct gp_config *read_config(char *config_file, char *config_dir, + char *socket_name, int opt_daemonize) { const char *socket = GP_SOCKET_NAME; + const char *dir = PUBCONF_PATH; struct gp_config *cfg; int ret; @@ -514,17 +516,24 @@ struct gp_config *read_config(char *config_file, char *socket_name, if (config_file) { cfg->config_file = strdup(config_file); if (!cfg->config_file) { - free(cfg); - return NULL; + ret = ENOMEM; + goto done; } } else { ret = asprintf(&cfg->config_file, "%s/gssproxy.conf", PUBCONF_PATH); if (ret == -1) { - free(cfg); - return NULL; + goto done; } } + if (config_dir) dir = config_dir; + + cfg->config_dir = strdup(dir); + if (!cfg->config_dir) { + ret = ENOMEM; + goto done; + } + if (socket_name) socket = socket_name; cfg->socket_name = strdup(socket); @@ -546,12 +555,14 @@ struct gp_config *read_config(char *config_file, char *socket_name, ret = load_config(cfg); if (ret) { - GPDEBUG("Config file not found!\n"); + GPDEBUG("Config file(s) not found!\n"); } done: if (ret) { + /* recursively frees cfg */ free_config(&cfg); + return NULL; } return cfg; @@ -585,45 +596,34 @@ void free_config(struct gp_config **cfg) *cfg = NULL; } -int gp_config_init(const char *config_file, - struct gp_ini_context *ctx) +static int gp_config_from_file(const char *config_file, + struct gp_ini_context *ctx, + struct ini_cfgobj *ini_config, + const uint32_t collision_flags) { - struct ini_cfgobj *ini_config = NULL; struct ini_cfgfile *file_ctx = NULL; int ret; - if (!ctx) { - return EINVAL; - } - - ret = ini_config_create(&ini_config); - if (ret) { - return ENOENT; - } - ret = ini_config_file_open(config_file, 0, /* metadata_flags, FIXME */ &file_ctx); if (ret) { GPDEBUG("Failed to open config file: %d (%s)\n", - ret, gp_strerror(ret)); + ret, gp_strerror(ret)); ini_config_destroy(ini_config); return ret; } ret = ini_config_parse(file_ctx, INI_STOP_ON_ANY, /* error_level */ - /* Merge section but allow duplicates */ - INI_MS_MERGE | - INI_MV1S_ALLOW | - INI_MV2S_ALLOW, + collision_flags, INI_PARSE_NOWRAP, /* parse_flags */ ini_config); if (ret) { char **errors = NULL; /* we had a parsing failure */ GPDEBUG("Failed to parse config file: %d (%s)\n", - ret, gp_strerror(ret)); + ret, gp_strerror(ret)); if (ini_config_error_count(ini_config)) { ini_config_get_errors(ini_config, &errors); if (errors) { @@ -637,6 +637,106 @@ int gp_config_init(const char *config_file, } ini_config_file_destroy(file_ctx); + return 0; +} + +static int gp_config_from_dir(const char *config_dir, + struct gp_ini_context *ctx, + struct ini_cfgobj **ini_config, + const uint32_t collision_flags) +{ + struct ini_cfgobj *result_cfg = NULL; + struct ref_array *error_list = NULL; + int ret; + + const char *patterns[] = { + /* match only files starting with "##-" and ending in ".conf" */ + "^[0-9]\\{2\\}-.\\{1,\\}\\.conf$", + NULL, + }; + + const char *sections[] = { + /* match either "gssproxy" or sections that start with "service/" */ + "^gssproxy$", + "^service/.*$", + NULL, + }; + + /* Permission check failures silently skip the file, so they are not + * useful to us. */ + ret = ini_config_augment(*ini_config, + config_dir, + patterns, + sections, + NULL, /* check_perm */ + INI_STOP_ON_ANY, /* error_level */ + collision_flags, + INI_PARSE_NOWRAP, + /* do not allow colliding sections with the same + * name in different files */ + INI_MS_ERROR, + &result_cfg, + &error_list, + NULL); + if (ret) { + if (error_list) { + uint32_t i; + uint32_t len = ref_array_getlen(error_list, &i); + for (i = 0; i < len; i++) { + GPDEBUG("Error when reading config directory: %s\n", + (const char *) ref_array_get(error_list, i, NULL)); + } + ref_array_destroy(error_list); + } else { + GPDEBUG("Error when reading config directory number: %d\n", ret); + } + return ret; + } + + /* if we read no new files, result_cfg will be NULL */ + if (result_cfg) { + ini_config_destroy(*ini_config); + *ini_config = result_cfg; + } + return 0; +} + +int gp_config_init(const char *config_file, const char *config_dir, + struct gp_ini_context *ctx) +{ + struct ini_cfgobj *ini_config = NULL; + int ret; + + /* Within a single file, merge all collisions */ + const uint32_t collision_flags = + INI_MS_MERGE | INI_MV1S_ALLOW | INI_MV2S_ALLOW; + + if (!ctx) { + return EINVAL; + } + + ret = ini_config_create(&ini_config); + if (ret) { + return ENOENT; + } + + if (config_file) { + ret = gp_config_from_file(config_file, ctx, ini_config, + collision_flags); + if (ret == ENOENT) { + GPDEBUG("Expected config file %s but did not find it.\n", + config_file); + } else if (ret) { + return ret; + } + } + if (config_dir) { + ret = gp_config_from_dir(config_dir, ctx, &ini_config, + collision_flags); + if (ret) { + return ret; + } + } ctx->private_data = ini_config; diff --git a/proxy/src/gp_config.h b/proxy/src/gp_config.h index 9d0d1d7..1bc756c 100644 --- a/proxy/src/gp_config.h +++ b/proxy/src/gp_config.h @@ -31,7 +31,7 @@ struct gp_ini_context { void *private_data; }; -int gp_config_init(const char *config_file, +int gp_config_init(const char *config_file, const char *config_dir, struct gp_ini_context *ctx); int gp_config_get_string(struct gp_ini_context *ctx, const char *secname, diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index 68c724c..72bbc5c 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -68,6 +68,7 @@ struct gp_service { struct gp_config { char *config_file; /* gssproxy configuration file */ + char *config_dir; /* gssproxy configuration directory */ bool daemonize; /* let gssproxy daemonize */ char *socket_name; /* the socket name to use for */ int num_workers; /* number of worker threads */ @@ -101,8 +102,8 @@ struct gp_call_ctx { }; /* from gp_config.c */ -struct gp_config *read_config(char *config_file, char *socket_name, - int opt_daemonize); +struct gp_config *read_config(char *config_file, char *config_dir, + char *socket_name, int opt_daemonize); struct gp_creds_handle *gp_service_get_creds_handle(struct gp_service *svc); void free_config(struct gp_config **config); diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c index 354d595..0e84859 100644 --- a/proxy/src/gssproxy.c +++ b/proxy/src/gssproxy.c @@ -36,6 +36,7 @@ int main(int argc, const char *argv[]) int opt_interactive = 0; int opt_version = 0; char *opt_config_file = NULL; + char *opt_config_dir = NULL; char *opt_config_socket = NULL; int opt_debug = 0; verto_ctx *vctx; @@ -55,6 +56,8 @@ int main(int argc, const char *argv[]) _("Run interactive (not a daemon)"), NULL}, \ {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \ _("Specify a non-default config file"), NULL}, \ + {"configdir", 'C', POPT_ARG_STRING, &opt_config_dir, 0, \ + _("Specify a non-default config directory"), NULL}, \ {"socket", 's', POPT_ARG_STRING, &opt_config_socket, 0, \ _("Specify a custom default socket"), NULL}, \ {"debug", 'd', POPT_ARG_NONE, &opt_debug, 0, \ @@ -90,6 +93,13 @@ int main(int argc, const char *argv[]) return 1; } + if (opt_config_file && opt_config_dir) { + fprintf(stderr, "Option -C|--configdir is not allowed together with" + " -c|--config\n"); + poptPrintUsage(pc, stderr, 0); + return 1; + } + if (opt_interactive) { opt_daemon = 2; } @@ -97,6 +107,7 @@ int main(int argc, const char *argv[]) gpctx = calloc(1, sizeof(struct gssproxy_ctx)); gpctx->config = read_config(opt_config_file, + opt_config_dir, opt_config_socket, opt_daemon); if (!gpctx->config) { |